Personal tools

GObjectIntrospection

From HaskellWiki

Revision as of 21:41, 2 January 2012 by DafyddHarries (Talk | contribs)

Jump to: navigation, search

GObject Introspection is a set of tools designed to simplify higher-level language bindings for C libraries based on GLib and GObject (including Gtk, GStreamer, Clutter and many others). By scanning the library's source at build time for specially-formatted comments, a repository is created containing information on the symbols and types exported by the library.

For Python and JavaScript, these repositories are loaded at runtime. For Haskell, we should be able to use them to automate writing the boring parts of the binding, freeing the binding author to focus on a beautiful Haskell layer atop them.

1 Work so far

These Git repositories on GitHub and git.rhydd.org (which one is further ahead depends on who's been hacking on it recently!) contain a Haskell binding for the GIRepository C library, and a Haskell code generator built upon it. It is very much a work in progress. Help appreciated!

The hope is that this could ultimately be merged with Gtk2Hs.

2 Status

As of January 2012:

  • bindings that compile can be generated for many modules, including Gtk
  • some function and method calls work
  • maybe-null arguments and return values are not handled correctly
  • signals are not working yet
  • reference counting is not implemented (everything leaks)

3 GObject Introspection primer

C library developers add annotations to their source comments to provide type and reference-counting information beyond what can be inferred from the C types. For example, consider this hypothetical function declaration with accompanying GtkDoc comment:

/**
 * foo_widget_get_children:
 * @self: A #FooWidget
 * @class: (allow-none): the name of a class of children to fetch,
 *     or %NULL to fetch all children.
 *
 * Returns: (element-type Foo.Child) (transfer container): the
 *     matching children.
 */
GList *
foo_widget_get_children (
   FooWidget *self,
   const gchar *class);

From the C type, we can infer that the function takes some object and a constant string, and returns a linked list of … something.

The annotations—underlined above—tell us that the caller may pass NULL for the string argument; and that the returned value is a list of FooChild objects. The caller is required to free the returned GList, but does not need to free the returned FooChild objects. So in Haskell, we could generate a function which looks like this:

module Foo where
 
widgetGetChildren :: WidgetClass self
                  -> self             -- ^ a widget
                  -> Maybe String     -- ^ an optional class of children
                  -> IO [Child]

Previously, the human writing a binding for a new class in a GObject library would have to figure out this information from reading the library documentation. Of course, if the annotations are incorrect, then the binding may crash—but equally, if the human binding author trusts incorrect source comments, the binding will crash in the same way. Since GObject Introspection is used by (among other key components) the Gnome Shell, the annotations stand a reasonable chance of being correct, and errors will break other, more mainstream bindings, not just Haskell code.