|  |  |  |  | 
Closures are central to the concept of asynchronous signal delivery which is widely used throughout GTK+ and GNOME applications. A closure is an abstraction, a generic representation of a callback. It is a small structure which contains three objects:
a function pointer (the callback itself) whose prototype looks like:
| 1 | return_type function_callback (... , gpointer user_data); | 
the user_data pointer which is passed to the callback upon invocation of the closure
a function pointer which represents the destructor of the closure: whenever the closure's refcount reaches zero, this function will be called before the closure structure is freed.
The GClosure structure represents the common functionality of all closure implementations: there exists a different Closure implementation for each separate runtime which wants to use the GObject type system. [6] The GObject library provides a simple GCClosure type which is a specific implementation of closures to be used with C/C++ callbacks.
A GClosure provides simple services:
          Invocation (g_closure_invoke): this is what closures 
          were created for: they hide the details of callback invocation from the
          callback invoker.
          Notification: the closure notifies listeners of certain events such as
          closure invocation, closure invalidation and closure finalization. Listeners
          can be registered with g_closure_add_finalize_notifier
          (finalization notification), g_closure_add_invalidate_notifier 
          (invalidation notification) and 
          g_closure_add_marshal_guards (invocation notification).
          There exist symmetric deregistration functions for finalization and invalidation
          events (g_closure_remove_finalize_notifier and
          g_closure_remove_invalidate_notifier) but not for the invocation 
          process.
          [7]
        If you are using C or C++
        to connect a callback to a given event, you will either use simple GCClosures
        which have a pretty minimal API or the even simpler g_signal_connect 
        functions (which will be presented a bit later :).
| 1 2 3 4 5 6 7 8 | GClosure *g_cclosure_new (GCallback callback_func, gpointer user_data, GClosureNotify destroy_data); GClosure *g_cclosure_new_swap (GCallback callback_func, gpointer user_data, GClosureNotify destroy_data); GClosure *g_signal_type_cclosure_new (GType itype, guint struct_offset); | 
        g_cclosure_new will create a new closure which can invoke the
        user-provided callback_func with the user-provided user_data as last parameter. When the closure
        is finalized (second stage of the destruction process), it will invoke the destroy_data function 
        if the user has supplied one.
      
        g_cclosure_new_swap will create a new closure which can invoke the
        user-provided callback_func with the user-provided user_data as first parameter (instead of being the 
        last parameter as with g_cclosure_new). When the closure
        is finalized (second stage of the destruction process), it will invoke the destroy_data 
        function if the user has supplied one.
      
As was explained above, closures hide the details of callback invocation. In C, callback invocation is just like function invocation: it is a matter of creating the correct stack frame for the called function and executing a call assembly instruction.
C closure marshallers transform the array of GValues which represent the parameters to the target function into a C-style function parameter list, invoke the user-supplied C function with this new parameter list, get the return value of the function, transform it into a GValue and return this GValue to the marshaller caller.
The following code implements a simple marshaller in C for a C function which takes an integer as first parameter and returns void.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | g_cclosure_marshal_VOID__INT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__INT) (gpointer data1, gint arg_1, gpointer data2); register GMarshalFunc_VOID__INT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 2); data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_int (param_values + 1), data2); } | 
        Of course, there exist other kinds of marshallers. For example, James Henstridge 
        wrote a generic Python marshaller which is used by all Python closures (a Python closure
        is used to have Python-based callback be invoked by the closure invocation process).
        This Python marshaller transforms the input GValue list representing the function 
        parameters into a Python tuple which is the equivalent structure in Python (you can
        look in pyg_closure_marshal in pygtype.c
        in the pygobject module in the GNOME source code repository).
      
[6] In practice, closures sit at the boundary of language runtimes: if you are writing Python code and one of your Python callbacks receives a signal from a GTK+ widget, the C code in GTK+ needs to execute your Python code. The closure invoked by the GTK+ object invokes the Python callback: it behaves as a normal C object for GTK+ and as a normal Python object for Python code.
[7] Closures are reference counted and notify listeners of their destruction in a two-stage process: the invalidation notifiers are invoked before the finalization notifiers.