GObject のオブジェクト (インスタンス) は、シグナルを使って任意の関数を呼び出すことができます。
以下のファイルを signal.c という名前で記述してください。
#include <glib-object.h>
G_DECLARE_FINAL_TYPE (MyObj, my_obj, MY, OBJ, GObject)
static guint n1, n2;
typedef struct _MyObj MyObj;
struct _MyObj
{
GObject parent;
int num;
};
static void
my_obj_init (MyObj *self) {}
G_DEFINE_TYPE (MyObj, my_obj, G_TYPE_OBJECT)
static void
my_obj_class_init(MyObjClass *klass) {
n1 = g_signal_new(
"send",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
0, NULL, NULL, NULL, G_TYPE_NONE, 0, NULL);
n2 = g_signal_new(
"quit",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
0, NULL, NULL, NULL, G_TYPE_NONE, 0, NULL);
}
static void
hello ()
{
g_print ("Hello.\n");
}
static void
bye ()
{
g_print ("Bye...\n");
exit(0);
}
int
main (int argc, char **argv)
{
GType type;
MyObj *obj;
type = my_obj_get_type ();
if (type)
g_print ("Registration successed : %lx\n", type);
else
g_print ("Registration failed.\n");
obj = g_object_new (my_obj_get_type (), NULL);
if (obj)
g_print ("Instantiation successed : %p\n", obj);
else
g_print ("Instantiation failed.\n");
if (MY_IS_OBJ (obj))
g_print ("obj is MyObj instance.\n");
if (G_IS_OBJECT (obj))
g_print ("obj is GObject instance.\n");
g_signal_connect (obj, "send", G_CALLBACK (hello), NULL);
g_signal_connect (obj, "quit", G_CALLBACK (bye), NULL);
g_signal_emit (obj, n1, 0);
g_signal_emit (obj, n2, 0);
g_signal_emit (obj, n1, 0);
g_object_unref (obj);
return 0;
}
シグナルと通常の関数の呼び出しと何が違うのかという感じですが、今回は g_signal_emit でシグナルを強制的に送っています。 これが通常の GUI アプリケーションの場合だとボタンをクリックしたときなどに、g_signal_connect で、リスナー (ハンドラー) の関数が呼び出されます。
以下のとおりです。Windows の場合は通常版でも ARM64版 でも mingw64 で行ってください。
// コンパイル
cc signal.c -o signal `pkg-config --cflags --libs gtk4`
// 実行
./signal
// 結果
Registration successed : 600002609440
Instantiation successed : 0x60000020a360
obj is MyObj instance.
obj is GObject instance.
Hello.
Bye...