Using Introspection to listen to a set of signals unknown at compile time [dbus-glib]

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Oct 23 04:54:05 PDT 2009


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

I hope your application is some sort of debugging tool; if it's not, please
consider writing a well-defined D-Bus API in which signals and methods have
known signatures (you can use the 'v' variant type, or maps from string to
variant (i.e. a{sv}), to provide extension points). You'll find that all the
major bindings work much better if you do that.

If that's not possible, then you'll have to stop using dbus-glib, and use a
lower-level API, like libdbus or the dbus.lowlevel part of dbus-python.

On Thu, 22 Oct 2009 at 21:39:35 -0400, Ed Martin wrote:
> Basically I want to write an application that can listen to signals 
> determined at runtime (loaded from a config file). I was told that for 
> an application written in C dbus-glib is the way to go (and it is going 
> to stay in C because it will eventually become a plugin to a larger 
> application written in C).

dbus-glib is too simple for what you're trying to do; for this functionality
you'll have to use libdbus directly (add a match rule, and add a filter
function to look for the signals).

>      Since I do not know the signals at compile time I can't know their 
> types, that makes dbus_g_proxy_add_signal() completely useless. 
> According to the docs, thats ok as long as the application supports 
> introspection.

That statement in the docs is not true. It's just as well, because if the docs
were true, services could remotely segfault clients by changing their reply
to Introspect().

> dbus_g_proxy_connect_signal(sess_proxy, name, 
> G_CALLBACK(lcd_sig_received), "lol", NULL);

What parameters do you think lcd_sig_received would take? You don't know the
type for dbus_g_proxy_add_signal, but neither do you know the type in order
to write lcd_sig_received() with the correct signature.

For instance, if you assume that the signal has two uint32 parameters, you'd
write:

static void lcd_sig_received (DBusGProxy *sess_proxy, guint a, guint b,
    gpointer user_data)

but if the signal actually had one array of strings as its parameter, your
callback would be called with parameters (DBusGProxy *sess_proxy,
GStrv *strings, gpointer user_data2) placed on the stack.

On a 32-bit platform (for example) you'd get a = GPOINTER_TO_UINT(strings),
b = GPOINTER_TO_UINT(user_data2), and user_data undefined; a and b would be
meaningless, and in any application where user_data is dereferenced by the
callback (in practice you usually need to), doing so would crash you
immediately.

If you write a libdbus filter function, on the other hand, you'll receive a
pointer to a DBusMessage object, which is self-describing (admittedly with a
particularly annoying API); your filter function can do the recursive
unmarshalling itself, in as elaborate a way as you want.

> I know of 
> many applications using many different bindings that are able to read 
> signals unknown at compile time (like dbus-monitor and d-feet).

Yes, but neither of those uses dbus-glib...

dbus-monitor uses libdbus, and unmarshals each message (to turn it into
text) on-demand.

d-feet uses libdbus via (the low-level part of) dbus-python; dbus-python only
uses dbus-glib for main loop integration.

Regards,
    Simon
-----BEGIN PGP SIGNATURE-----

iQIVAwUBSuGZVE3o/ypjx8yQAQhYOxAAjeA2XkdXWLWyv1OfZUxwx/RcDiXornhG
8iu7zckqHczHssjKLOyzf2JuMO8L6Htmzm7yaOyN0VG2ZS0ugryZzIGo5Hl19g/i
UkZ94XnMexpLB+Z0BRwVCchDWYnKdfaiEEJ/UVxDBPighSo7ujsf/S72SnaK+osF
Esb2gfDI/VADvqQ0v1V+9rVDf7ChoJlnw5ce6k3o28HUXUSeAa3Lz1wA5OBg4juB
FjVGj11msVZstZXWAgQggN22Nt5eYZpD3TUKZ6FDoPHR13uRNd5IH8Jah/F1amNh
PK6QxIM5tO+sPCF01s+FUBDVPKPBEamX+TD8CQpfOwOPQPGnms90KpMXyueefVNy
uNRnkR0WnLhqEHRdRhBbFHPUNfm+30ycwMI1R1VqjldFFb5NBa8WV/z5yO8T693a
It/nRn+VXCTTBQJ8MlguMS5ArVo7MsHDWXDCdcEVJSgB3cigx3nTqC2zgypJDqe4
10twFZBryJLVSWDdGM3sGvg/UDL+lEH1U+3t02glqUDBuqfWOAJKtyAbGdWxEV7v
frgK0+Ekjzv/LVigiBHXWSFwvoBRo7wdqil3M/XrpkpMFtOEotFxpLqZwsyJibVK
yN8jW2bomrUo3049Ckr3CEkThYfNnMJzGNn2Ci6S8ubhpS/egHB/JNn5c1pFRRTW
0gvfDh2/7Jc=
=27SJ
-----END PGP SIGNATURE-----


More information about the dbus mailing list