создавать и излучать сигнал GTK

Я пытаюсь создать и испустить сигнал 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_invoke: утверждение `закрытие-> маршал || завершение -> meta_marshal 'не удалось

Я знаю, что это как-то связано с передачей маршаллера в g_signal_newфункцию, но я не знаю, что такое маршаллер, я не могу понять документацию , и примеров в Интернете мало, и они далеко друг от друга. Как мне объявить и подключить свой собственный сигнал?

12.10.2009 21:23:11
1 ОТВЕТ
РЕШЕНИЕ

Библиотека 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).

3
12.10.2009 21:47:52
Просто исправление сказанного выше: GBoxed-типы не имеют проверки типов, они являются только оболочками для структур Си без информации о типах. Реальная разница между G_TYPE_POINTER и G_TYPE_BOXED заключается в том, что в последнем используется копия структуры GdkEvent. Если событие не изменено, это не имеет значения, но если вам нужно изменить его, используйте G_TYPE_POINTER.
ntd 12.10.2009 23:08:44