|
Packit |
ae235b |
|
|
Packit |
ae235b |
<html>
|
|
Packit |
ae235b |
<head>
|
|
Packit |
ae235b |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
Packit |
ae235b |
<title>The GObject messaging system: GObject Reference Manual</title>
|
|
Packit |
ae235b |
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
|
|
Packit |
ae235b |
<link rel="home" href="index.html" title="GObject Reference Manual">
|
|
Packit |
ae235b |
<link rel="up" href="pt01.html" title="Part I. Concepts">
|
|
Packit |
ae235b |
<link rel="prev" href="gobject-properties.html" title="Object properties">
|
|
Packit |
ae235b |
<link rel="next" href="signal.html" title="Signals">
|
|
Packit |
ae235b |
<meta name="generator" content="GTK-Doc V1.27 (XML mode)">
|
|
Packit |
ae235b |
<link rel="stylesheet" href="style.css" type="text/css">
|
|
Packit |
ae235b |
</head>
|
|
Packit |
ae235b |
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
The GObject messaging system
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Closures
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
C Closures
|
|
Packit |
ae235b |
Non-C closures (for the fearless)
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Signals
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Signal registration
|
|
Packit |
ae235b |
Signal connection
|
|
Packit |
ae235b |
Signal emission
|
|
Packit |
ae235b |
The detail argument
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Closures
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Closures are central to the concept of asynchronous signal delivery
|
|
Packit |
ae235b |
which is widely used throughout GTK+ and GNOME applications. A closure is an
|
|
Packit |
ae235b |
abstraction, a generic representation of a callback. It is a small structure
|
|
Packit |
ae235b |
which contains three objects:
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
a function pointer (the callback itself) whose prototype looks like:
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
1
|
|
Packit |
ae235b |
return_type function_callback (… , gpointer user_data);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
the user_data pointer which is passed to the callback upon invocation of the closure
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
a function pointer which represents the destructor of the closure: whenever the
|
|
Packit |
ae235b |
closure's refcount reaches zero, this function will be called before the closure
|
|
Packit |
ae235b |
structure is freed.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
The GClosure structure represents the common functionality of all
|
|
Packit |
ae235b |
closure implementations: there exists a different closure implementation for
|
|
Packit |
ae235b |
each separate runtime which wants to use the GObject type system.
|
|
Packit |
ae235b |
<sup class="footnote">[4]</sup>
|
|
Packit |
ae235b |
The GObject library provides a simple GCClosure type which
|
|
Packit |
ae235b |
is a specific implementation of closures to be used with C/C++ callbacks.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
A GClosure provides simple services:
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Invocation (g_closure_invoke ): this is what closures
|
|
Packit |
ae235b |
were created for: they hide the details of callback invocation from the
|
|
Packit |
ae235b |
callback invoker.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Notification: the closure notifies listeners of certain events such as
|
|
Packit |
ae235b |
closure invocation, closure invalidation and closure finalization. Listeners
|
|
Packit |
ae235b |
can be registered with g_closure_add_finalize_notifier
|
|
Packit |
ae235b |
(finalization notification), g_closure_add_invalidate_notifier
|
|
Packit |
ae235b |
(invalidation notification) and
|
|
Packit |
ae235b |
g_closure_add_marshal_guards (invocation notification).
|
|
Packit |
ae235b |
There exist symmetric deregistration functions for finalization and invalidation
|
|
Packit |
ae235b |
events (g_closure_remove_finalize_notifier and
|
|
Packit |
ae235b |
g_closure_remove_invalidate_notifier ) but not for the invocation
|
|
Packit |
ae235b |
process.
|
|
Packit |
ae235b |
<sup class="footnote">[5]</sup>
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
C Closures
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
If you are using C or C++
|
|
Packit |
ae235b |
to connect a callback to a given event, you will either use simple GCClosures
|
|
Packit |
ae235b |
which have a pretty minimal API or the even simpler g_signal_connect
|
|
Packit |
ae235b |
functions (which will be presented a bit later).
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_cclosure_new will create a new closure which can invoke the
|
|
Packit |
ae235b |
user-provided callback_func with the user-provided
|
|
Packit |
ae235b |
user_data as its last parameter. When the closure
|
|
Packit |
ae235b |
is finalized (second stage of the destruction process), it will invoke
|
|
Packit |
ae235b |
the destroy_data function if the user has
|
|
Packit |
ae235b |
supplied one.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_cclosure_new_swap will create a new closure which can invoke the
|
|
Packit |
ae235b |
user-provided callback_func with the
|
|
Packit |
ae235b |
user-provided user_data as its first parameter
|
|
Packit |
ae235b |
(instead of being the
|
|
Packit |
ae235b |
last parameter as with g_cclosure_new ). When the closure
|
|
Packit |
ae235b |
is finalized (second stage of the destruction process), it will invoke
|
|
Packit |
ae235b |
the destroy_data function if the user has
|
|
Packit |
ae235b |
supplied one.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Non-C closures (for the fearless)
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
As was explained above, closures hide the details of callback invocation. In C,
|
|
Packit |
ae235b |
callback invocation is just like function invocation: it is a matter of creating
|
|
Packit |
ae235b |
the correct stack frame for the called function and executing a call
|
|
Packit |
ae235b |
assembly instruction.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
C closure marshallers transform the array of GValues which represent
|
|
Packit |
ae235b |
the parameters to the target function into a C-style function parameter list, invoke
|
|
Packit |
ae235b |
the user-supplied C function with this new parameter list, get the return value of the
|
|
Packit |
ae235b |
function, transform it into a GValue and return this GValue to the marshaller caller.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
A generic C closure marshaller is available as
|
|
Packit |
ae235b |
g_cclosure_marshal_generic
|
|
Packit |
ae235b |
which implements marshalling for all function types using libffi. Custom
|
|
Packit |
ae235b |
marshallers for different types are not needed apart from performance
|
|
Packit |
ae235b |
critical code where the libffi-based marshaller may be too slow.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
An example of a custom marshaller is given below, illustrating how
|
|
Packit |
ae235b |
GValues can be converted to a C function call. The
|
|
Packit |
ae235b |
marshaller is for a C function which takes an integer as its first
|
|
Packit |
ae235b |
parameter and returns void.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
1
|
|
Packit |
ae235b |
2
|
|
Packit |
ae235b |
3
|
|
Packit |
ae235b |
4
|
|
Packit |
ae235b |
5
|
|
Packit |
ae235b |
6
|
|
Packit |
ae235b |
7
|
|
Packit |
ae235b |
8
|
|
Packit |
ae235b |
9
|
|
Packit |
ae235b |
10
|
|
Packit |
ae235b |
11
|
|
Packit |
ae235b |
12
|
|
Packit |
ae235b |
13
|
|
Packit |
ae235b |
14
|
|
Packit |
ae235b |
15
|
|
Packit |
ae235b |
16
|
|
Packit |
ae235b |
17
|
|
Packit |
ae235b |
18
|
|
Packit |
ae235b |
19
|
|
Packit |
ae235b |
20
|
|
Packit |
ae235b |
21
|
|
Packit |
ae235b |
22
|
|
Packit |
ae235b |
23
|
|
Packit |
ae235b |
24
|
|
Packit |
ae235b |
25
|
|
Packit |
ae235b |
g_cclosure_marshal_VOID__INT (GClosure *closure,
|
|
Packit |
ae235b |
GValue *return_value,
|
|
Packit |
ae235b |
guint n_param_values,
|
|
Packit |
ae235b |
const GValue *param_values,
|
|
Packit |
ae235b |
gpointer invocation_hint,
|
|
Packit |
ae235b |
gpointer marshal_data)
|
|
Packit |
ae235b |
{
|
|
Packit |
ae235b |
typedef void (*GMarshalFunc_VOID__INT) (gpointer data1,
|
|
Packit |
ae235b |
gint arg_1,
|
|
Packit |
ae235b |
gpointer data2);
|
|
Packit |
ae235b |
register GMarshalFunc_VOID__INT callback;
|
|
Packit |
ae235b |
register GCClosure *cc = (GCClosure*) closure;
|
|
Packit |
ae235b |
register gpointer data1, data2;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
g_return_if_fail (n_param_values == 2);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
data1 = g_value_peek_pointer (param_values + 0);
|
|
Packit |
ae235b |
data2 = closure->data;
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
callback (data1,
|
|
Packit |
ae235b |
g_marshal_value_peek_int (param_values + 1),
|
|
Packit |
ae235b |
data2);
|
|
Packit |
ae235b |
}
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
There exist other kinds of marshallers, for example there is a generic
|
|
Packit |
ae235b |
Python marshaller which is used by all Python closures (a Python closure
|
|
Packit |
ae235b |
is used to invoke a callback written in Python). This Python marshaller
|
|
Packit |
ae235b |
transforms the input GValue list representing the function parameters
|
|
Packit |
ae235b |
into a Python tuple which is the equivalent structure in Python.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
In practice, closures sit at the boundary of language runtimes: if you are
|
|
Packit |
ae235b |
writing Python code and one of your Python callbacks receives a signal from
|
|
Packit |
ae235b |
a GTK+ widget, the C code in GTK+ needs to execute your Python
|
|
Packit |
ae235b |
code. The closure invoked by the GTK+ object invokes the Python callback:
|
|
Packit |
ae235b |
it behaves as a normal C object for GTK+ and as a normal Python object for
|
|
Packit |
ae235b |
Python code.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Closures are reference counted and notify listeners of their destruction in a two-stage
|
|
Packit |
ae235b |
process: the invalidation notifiers are invoked before the finalization notifiers.
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
Generated by GTK-Doc V1.27
|
|
Packit |
ae235b |
</body>
|
|
Packit |
ae235b |
</html>
|