Personal tools

GObjectIntrospection

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
(Quick overview of haskell-gi)
 
(Work so far)
 
(5 intermediate revisions by 3 users not shown)
Line 5: Line 5:
 
== Work so far ==
 
== Work so far ==
   
These Git repositories on [https://gitorious.org/haskell-gi Gitorious] and [http://git.rhydd.org/?p=haskell-gi 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!
+
These Git repositories on [https://github.com/garetxe/haskell-gi GitHub/garetxe], [https://github.com/wjt/haskell-gi GitHub/wjt] and [http://git.rhydd.org/?p=haskell-gi 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]].
 
The hope is that this could ultimately be merged with [[Gtk2Hs]].
  +
  +
== Status ==
  +
  +
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 ==
 
== GObject Introspection primer ==
Line 16: Line 32:
 
* foo_widget_get_children:
 
* foo_widget_get_children:
 
* @self: A #FooWidget
 
* @self: A #FooWidget
* @class: <ins>(allow-none):</ins> the name of a class of children to fetch, or %NULL
+
* @class: <ins>(allow-none):</ins> the name of a class of children to fetch,
* to fetch all children.
+
* or %NULL to fetch all children.
 
*
 
*
 
* Returns: <ins>(element-type Foo.Child) (transfer container):</ins> the
 
* Returns: <ins>(element-type Foo.Child) (transfer container):</ins> the
Line 29: Line 45:
 
From the C type, we can infer that the function takes some object and a constant string, and returns a linked list of … something.
 
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.
+
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:
  +
  +
<haskell>
  +
module Foo where
  +
  +
widgetGetChildren :: WidgetClass self
  +
-> self -- ^ a widget
  +
-> Maybe String -- ^ an optional class of children
  +
-> IO [Child]
  +
</haskell>
   
 
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.
 
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.

Latest revision as of 10:13, 1 October 2013

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.

[edit] 1 Work so far

These Git repositories on GitHub/garetxe, GitHub/wjt 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.

[edit] 2 Status

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)

[edit] 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.