结构
GObjectClosure
描述 [src]
struct GClosure {
guint in_marshal : 1;
guint is_invalid : 1;
void (* marshal) (
GClosure* closure,
GValue* return_value,
guint n_param_values,
const GValue* param_values,
gpointer invocation_hint,
gpointer marshal_data
);
}
GClosure
表示程序员提供的回调。
它通常由某一类型的函数和用于调用它的编组程序组成。编组程序负责将调用所需的参数从 GValues
转换为合适的格式、使用已转换的参数执行回调并转换返回值以再次成为 GValue
。
对于 C 程序,closure 通常只保存指向函数的指针,可能还保存一个数据参数,编组程序会在 GValue
和 C 原生类型之间进行转换。GObject 库会提供 GCClosure
类型来实现此目的。其他语言的绑定需要编组程序,以便在语言运行时,使用 GValues
和合适表示内容之间进行转换,从而将该语言编写的函数用作回调。使用 g_closure_set_marshal()
为这种自定义 closure 实现设置编组程序。
在 GObject 中,closures 在信号实现中发挥重要作用。当信号注册时,g_signal_new()
中的 c_marshaller
参数会为任何与此信号连接的 closure 指定默认 C 编组程序。GObject 会为此目的提供许多 C 编组程序,请参见 g_cclosure_marshal_() 函数。额外的 C 编组程序可以使用 [glib-genmarshal][glib-genmarshal] 实用程序来生成。可以使用 g_signal_connect_closure() 将 closures 明确连接到信号,但通常借助 GObject 自动创建 closure 更方便,方法是使用任一接受回调函数/用户数据对的 g_signal_connect_() 函数。
使用 closures 比简单的回调函数/数据指针组合拥有许多重要优势
-
Closures 允许被调用者获取回调参数的类型,这意味着语言绑定不必为每种回调类型编写单独的粘合代码。
-
GClosure
的引用计数使正确处理可重入变得容易;如果回调在被调用时已删除,则该 closure 及其参数不会被释放,直至调用完成。 -
g_closure_invalidate()
和无效化通知程序允许在指向的对象消失时自动移除回调。
结构成员
in_marshal
指示闭包当前是否通过 g_closure_invoke() 执行。
is_invalid
指示闭包是否已通过 g_closure_invalidate() 失效。
marshal
没有可用描述。
构造器
g_closure_new_object
g_closure_new_simple()
的一个变体,它在闭包的 data
字段中存储 object
,并在 object
和创建的闭包上调用 g_object_watch_closure()
。此函数主要用于实现闭包的新类型时有用。