/**
* YggRxFunc:
* @addr: (transfer full): destination address of the data to be transmitted.
* @id: (transfer full): a UUID.
* @response_to: (transfer full) (nullable): a UUID the data is in response to
* or %NULL.
* @metadata: (transfer full) (nullable) (element-type utf8 utf8): a #GHashTable
* containing key-value pairs associated with the data or %NULL.
* @data: (transfer full): the data.
* @user_data: (transfer none) (closure): The owning #YggWorker instance.
*
* Signature for callback function used in ygg_worker_set_rx_func(). It is
* invoked each time the worker receives data from the dispatcher.
*/
typedef void (* YggRxFunc) (gchar *addr,
gchar *id,
gchar *response_to,
GHashTable *metadata,
GBytes *data,
gpointer user_data);
/**
* ygg_worker_set_rx_func:
* @worker: A #YggWorker instance.
* @rx: (scope call): A #YggRxFunc callback.
*
* Stores a pointer to a handler function that is invoked whenever data is
* received by the worker.
*
* Returns: %TRUE if setting the function handler succeeded.
*/
gboolean
ygg_worker_set_rx_func (YggWorker *self,
YggRxFunc rx)
{
YggWorkerPrivate *priv = ygg_worker_get_instance_private (self);
priv->rx = rx;
return TRUE;
}
This all works as expected when using this library in a C program, but when I use it through GObject Introspection in Python, the rx callback never gets invoked.
When I trigger the object (via the appropriate D-Bus method), I expect the rx callback to get invoked and print “in rx” to the console, but nothing happens. The various g_debug calls I have within the C library print, but as soon as the control flow shouldenter the rx function it just stops.
Am I doing something wrong with the annotations? Is there another way to properly label a Python function as a callback to a GObject Introspection library?
GHashTable does not have type information on its contents, and does not have ownership information on the data it contains either: the data can be copied, or can be stored as is. When you get a GHashTable you don’t know who is responsible for freeing its data when the hash table is gone, since the getter function is all without transfer information.
Do not mistake the fact that there’s an annotation and some barebones support in the introspection information and some bindings with the ability to properly describe what a GHashTable is, or contains. The same applies to GArray, GPtrArray, and even to the linked list types. All of the untyped data containers in GLib are meant to be used internally, not at the API boundary.
In the definition of this function, I would hold a reference to func to be called later. Is this user_data to be held as well, and passed into func when I invoke it later? When is the appropriate time to then call notify? After func has finished executing?
When you’re clearing the priv->rx field, e.g. in the dispose() or finalize() virtual function of your YggWorker object instance; or if somebody is setting a new “rx” function, for instance: