4

我正在尝试创建并发出 GTK 信号:

g_signal_new("child-finished",
    G_TYPE_OBJECT,
    G_SIGNAL_RUN_FIRST,
    0,
    NULL, NULL,
    NULL,           // *** I think this is where I need to change it
    G_TYPE_NONE, 0);
g_signal_connect(G_OBJECT(myWindow), "child-finished", G_CALLBACK(MyCallback), NULL);

这是我发出信号的代码:

gtk_signal_emit_by_name(referenceToMyWindow, "child-finished");

这是我处理信号的代码:

void MyCallback(GtkWidget *w, GdkEvent *e)
{
    // handler code here
}

当我运行代码时,出现以下错误:

GLib-GObject-CRITICAL **:g_closure_调用:断言 `closure->marshal || 关闭->meta_marshal' 失败

我知道这与将 marshaller 传递给g_signal_new函数有关,但我不知道 marshaller 是什么,我无法理解文档,并且在线示例很少而且相差甚远。如何声明和连接自己的信号?

4

1 回答 1

3

GObject 库提供了一些内置编组器,因此您的代码可能应该是:

g_signal_new("child-finished",
             G_TYPE_OBJECT, G_SIGNAL_RUN_FIRST,
             0, NULL, NULL,
             g_cclosure_marshal_VOID__POINTER,
             G_TYPE_NONE, 1, G_TYPE_POINTER);

或者,如果您想进行类型检查:

g_signal_new("child-finished",
             G_TYPE_OBJECT, G_SIGNAL_RUN_FIRST,
             0, NULL, NULL,
             g_cclosure_marshal_VOID__BOXED,
             G_TYPE_NONE, 1, GDK_TYPE_EVENT);

信号处理程序的参数必须存在(对象本身是隐含的),所以一定要指定一个指针(如第一个示例)或装箱类型(如第二个示例)。

如果您需要的编组器不在内置程序中,您可以使用glib-genmarshal实用程序或直接自己编写代码(这很简单,只需检查 glib-genmarshal 的输出即可)。

于 2009-10-12T21:47:52.607 回答