1、闭包
闭合是异步信号传输概念的核心,它广泛应用于GTK+和GNOME应用。闭包是抽象概念,是回调的一般表示形式。 它是一个小结构,包含三个对象:
(1)一个函数指针(回调本身),其原型如下:
return_type function_callback(...,gpointer user_data);
(2)在调用闭包时传递给回调的user_data指针
(3)一个表示闭包的析构函数的函数指针:每当闭包的引用计数达到零时,这个函数将在闭包结构被释放之前被调用。
GClosure结构体表示所有闭包实现的共同功能:每个正在使用的Gobject系统有不同的闭包实现。GObject库提供了一个简单的GCClosure类型,它是使用C/C++回调的闭包特定实现。
GClosure提供简单的服务:
(1)调用(g_closure_invoke):这是就是关闭创建的原因:它通过调用机制对调用者隐藏细节。
(2)通知:闭包通知监听者特定事件。如闭包调用,闭包无效和闭包结束可以使用g_closure_add_finalize_notifier(结束通知),g_closure_add_invalidate_notifier(失效通知)和g_closure_add_marshal_guards(调用通知)。存在用于完成和无效事件的对称注销功能(g_closure_remove_finalize_notifier和g_closure_remove_invalidate_notifier),但不适用于调用过程。
2、C语言闭包
如果你使用C或C++将回调连接到给定的事件,您将会使用简单的GCClosures,它们具有漂亮迷你的API或使用更简单的g_signal_connect函数(稍后会呈现)。g_cclosure_new将创建一个新的闭包,可以用用户提供的user_data作为其最后一个参数来调用用户提供的callback_func。当闭包完成(销毁过程的第二阶段)时,它将调用destroy_data函数如果用户提供了这个功能的话。
g_cclosure_new_swap将创建一个新的闭包,可以用用户提供的user_data作为其第一个参数(而不是g_cclosure_new的最后一个参数)来调用用户提供的callback_func。当关闭完成(销毁过程的第二阶段)时,它将调用destroy_data函数如果用户提供了这个功能的话。
3、非C语言闭包
通用的C闭包marshaller可以使用g_cclosure_marshal_generic生成,它使用libffi实现所有函数类型的marshalling。为了不同的类型定制marshallers
时不需要的除了使用基于库libffi实现的marshaller可能会比较慢导致性能很吃紧的代码
闭合是异步信号传输概念的核心,它广泛应用于GTK+和GNOME应用。闭包是抽象概念,是回调的一般表示形式。 它是一个小结构,包含三个对象:
(1)一个函数指针(回调本身),其原型如下:
return_type function_callback(...,gpointer user_data);
(2)在调用闭包时传递给回调的user_data指针
(3)一个表示闭包的析构函数的函数指针:每当闭包的引用计数达到零时,这个函数将在闭包结构被释放之前被调用。
GClosure结构体表示所有闭包实现的共同功能:每个正在使用的Gobject系统有不同的闭包实现。GObject库提供了一个简单的GCClosure类型,它是使用C/C++回调的闭包特定实现。
GClosure提供简单的服务:
(1)调用(g_closure_invoke):这是就是关闭创建的原因:它通过调用机制对调用者隐藏细节。
(2)通知:闭包通知监听者特定事件。如闭包调用,闭包无效和闭包结束可以使用g_closure_add_finalize_notifier(结束通知),g_closure_add_invalidate_notifier(失效通知)和g_closure_add_marshal_guards(调用通知)。存在用于完成和无效事件的对称注销功能(g_closure_remove_finalize_notifier和g_closure_remove_invalidate_notifier),但不适用于调用过程。
2、C语言闭包
如果你使用C或C++将回调连接到给定的事件,您将会使用简单的GCClosures,它们具有漂亮迷你的API或使用更简单的g_signal_connect函数(稍后会呈现)。g_cclosure_new将创建一个新的闭包,可以用用户提供的user_data作为其最后一个参数来调用用户提供的callback_func。当闭包完成(销毁过程的第二阶段)时,它将调用destroy_data函数如果用户提供了这个功能的话。
g_cclosure_new_swap将创建一个新的闭包,可以用用户提供的user_data作为其第一个参数(而不是g_cclosure_new的最后一个参数)来调用用户提供的callback_func。当关闭完成(销毁过程的第二阶段)时,它将调用destroy_data函数如果用户提供了这个功能的话。
3、非C语言闭包
如上所述,closures隐藏回调调用的细节。在C中,回调调用就像函数调用:它是为被调用函数创建正确的堆栈帧,并执行一个调用汇编指令。
C闭包marshallers将表示参数的GValues数组转换为C函数参数列表,使用该新参数列表调用用户提供的C函数,回调函数运行返回之后获取函数的返回值,将其转换
为GValue并将此GValue返回给marshaller调用者。通用的C闭包marshaller可以使用g_cclosure_marshal_generic生成,它使用libffi实现所有函数类型的marshalling。为了不同的类型定制marshallers
时不需要的除了使用基于库libffi实现的marshaller可能会比较慢导致性能很吃紧的代码
下面给出了一个自定义marshaller的例子,说明了如何将GValues转换为C函数调用。marshaller是一个C函数,它将一个整数作为其第一个参数并返回void。
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);
}
还有其他类型的marshallers,例如有一个通用的Python marshallers,被所有的Python闭包使用(一个Python闭包被用于一个用Python编写的回调)。
该Python marshallers将表示函数参数的输入GValue列表转换为Python元组,Python元素是Python中的等效结构。