GObjectIntrospection

From HaskellWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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 use them to automate writing the boring parts of the binding, freeing the binding author to focus on a beautiful Haskell layer atop them.

Work so far

The git repository at github contains the Haskell code generator built upon gobject-introspection. Help appreciated!

Status

As of January 2017:

  • The Haskell code generator at haskell-gi is now essentially complete: all the information exposed in the bindings should now be available from the autogenerated bindings. This includes ordinary functions, signals, virtual functions, structure fields, object properties, etc.
  • Whenever the original introspection data is correct, there should be neither crashes nor memory leaks in the generated bindings.
  • A higher level, more beautiful Haskell API is still missing. Helpful bindings for particularly awkward parts of the gtk+ API are available at [1].

As of March 2013:

  • signal callbacks are working
  • reference counting is implemented
  • working ownership transfer of function arguments

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)

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 Text     -- ^ 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.