about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/wrapped/wrappedgobject2_private.h6
-rwxr-xr-xtests/misc/gclosurebin0 -> 13312 bytes
-rw-r--r--tests/misc/gclosure.c69
-rw-r--r--tests/misc/gclosure.txt4
4 files changed, 76 insertions, 3 deletions
diff --git a/src/wrapped/wrappedgobject2_private.h b/src/wrapped/wrappedgobject2_private.h
index bced8c93..51c12010 100644
--- a/src/wrapped/wrappedgobject2_private.h
+++ b/src/wrapped/wrappedgobject2_private.h
@@ -77,15 +77,15 @@ GOM(g_closure_add_finalize_notifier, vFEppp)
 //GOM(g_closure_add_marshal_guards, vFppppp)
 GO(g_closure_get_type, LFv)
 //GOM(g_closure_invalidate, vFp)
-//GOM(g_closure_invoke, vFppupp)
+GO(g_closure_invoke, vFppupp)
 //GOM(g_closure_new_object, pFup)
 GO(g_closure_new_simple, pFup)
-//GOM(g_closure_ref, pFp)
+GO(g_closure_ref, pFp)
 GOM(g_closure_remove_finalize_notifier, vFEppp)
 //GOM(g_closure_remove_invalidate_notifier, vFppp)
 GOM(g_closure_set_marshal, vFEpp)
 //GOM(g_closure_set_meta_marshal, vFppp)
-//GOM(g_closure_sink, vFp)
+GO(g_closure_sink, vFp)
 GO(g_closure_unref, vFp)
 GO(g_date_get_type, LFv)
 GO(g_date_time_get_type, LFv)
diff --git a/tests/misc/gclosure b/tests/misc/gclosure
new file mode 100755
index 00000000..139c1209
--- /dev/null
+++ b/tests/misc/gclosure
Binary files differdiff --git a/tests/misc/gclosure.c b/tests/misc/gclosure.c
new file mode 100644
index 00000000..bdbc3304
--- /dev/null
+++ b/tests/misc/gclosure.c
@@ -0,0 +1,69 @@
+// gcc gclosure.c -o gclosure `pkg-config --cflags --libs gobject-2.0`
+#include <glib-object.h>
+
+typedef void (*MyCallback)(gint arg1, const gchar* arg2, gpointer user_data);
+
+void my_marshal(GClosure* closure,
+    GValue* return_value,
+    guint n_param_values,
+    const GValue* param_values,
+    gpointer invocation_hint,
+    gpointer marshal_data)
+{
+    g_return_if_fail(n_param_values == 3);
+
+    MyCallback callback;
+    callback = (MyCallback)g_value_get_pointer(&param_values[0]);
+
+    if (!callback)
+        return;
+
+    gint arg1 = g_value_get_int(&param_values[1]);
+    const gchar* arg2 = g_value_get_string(&param_values[2]);
+
+    callback(arg1, arg2, closure->data);
+}
+
+void example_callback(gint num, gchar* str, gpointer user_data)
+{
+    g_print("Callback called with: %d, '%s' (user_data: %p)\n",
+        num, str, user_data);
+}
+
+int main()
+{
+    GClosure* closure = g_closure_new_simple(sizeof(GClosure), NULL);
+    g_print("Initial refcount: %d\n", closure->ref_count);
+
+    g_closure_set_marshal(closure, my_marshal);
+
+    gpointer user_data = (gpointer)0x3a5000;
+    closure->data = user_data;
+
+    GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
+
+    g_value_init(&params[0], G_TYPE_POINTER);
+    g_value_set_pointer(&params[0], example_callback);
+
+    g_value_init(&params[1], G_TYPE_INT);
+    g_value_set_int(&params[1], 42);
+
+    g_value_init(&params[2], G_TYPE_STRING);
+    g_value_set_string(&params[2], "Hello GClosure");
+
+    GValue return_value = G_VALUE_INIT;
+    g_closure_invoke(closure, &return_value, 3, params, NULL);
+
+    g_closure_ref(closure);
+    g_print("After ref, refcount: %d\n", closure->ref_count);
+
+    g_closure_sink(closure);
+    g_print("After sinking, refcount: %d\n", closure->ref_count);
+
+    g_closure_unref(closure);
+    g_value_unset(&params[0]);
+    g_value_unset(&params[1]);
+    g_value_unset(&params[2]);
+
+    return 0;
+}
diff --git a/tests/misc/gclosure.txt b/tests/misc/gclosure.txt
new file mode 100644
index 00000000..eebbacb0
--- /dev/null
+++ b/tests/misc/gclosure.txt
@@ -0,0 +1,4 @@
+Initial refcount: 1
+Callback called with: 42, 'Hello GClosure' (user_data: 0x3a5000)
+After ref, refcount: 2
+After sinking, refcount: 1