Re: glib2/gdbus - arrays and g_variant_get() quirks
David Sommerseth <[email protected]>
| Newsgroups | gmane.comp.freedesktop.dbus |
|---|---|
| Message-ID | <[email protected]> |
On 10/10/17 17:53, Simon McVittie wrote: > On Mon, 09 Oct 2017 at 23:35:38 +0200, David Sommerseth wrote: [...snip...] >> But I'm not really happy about the '(*)'. So I change that to say: >> >> g_variant_get(res, "(au)", &array); > > You can't do this unless you change the type of 'array'. The format > string "(*)" expects a GVariant * argument, but the format string > "(au)" (or in fact "(aX)" for any X) expects a GVariantIter **. > > See: https://developer.gnome.org/glib/stable/gvariant-format-strings.html > > If you want both a GVariant * and type assertions, use "(@au)". > > In general, g_variant_get() and g_variant_new() are designed for > convenience, rather than maximum possible consistency - the thought is > "if you have something that you know to be an array, clearly you are > going to want to iterate over it". > > g_variant_get() with format string "(*)" or "(@au)" is effectively a > short-cut for calling g_variant_get_child_value() (and an assertion > about the type, in the case of "(@au)". > > g_variant_get() with format string "(au)" is effectively a short-cut > for calling g_variant_get_child_value(), g_variant_iter_new() and > g_variant_iter_init(). Ahh! Now I see! And yes, I understand I didn't think this through enough using GVariant * with (au). I switched to using GVariantIter, and things got a lot more simple. This explanation with the docs URL was key to make me understand how to resolve it. >> I do know that results from D-Bus are inside a "container", so the () >> encapsulation is needed. > > This is a true fact about the GDBus API for D-Bus, but it is not a > general fact about D-Bus. In generic D-Bus the hierarchy is: > > message > header > message type > object path > interface > etc. > body, consisting of 0-many times: > parameter > > In the GDBus API, the representation for a message body happens to be a > GVariant of type tuple, because that's a convenient way to encapsulate > 0 or more GVariant> > In other D-Bus APIs (like libdbus, and I think also sd-bus) there is no > representation for a message body as separate from a message. Aha ... Okay, this makes sense. I was recommended to have a closer look at sd-bus, but it wasn't easily available in RHEL7 outside the systemd project source (not even API stable in systemd 219). I did have a look at libdbus, but felt the complexity and documentation was poorer compared to glib2/gdbus. Plus several developers recommended to stay away from libdbus. > "Container" is a jargon term in the D-Bus and GVariant data-type models - > it means an array, a D-Bus struct or GVariant tuple (they're the same > thing), a variant, a dict-entry or a GVariant "maybe" type - so it's > best to avoid using that word with its generic meaning. Right ... I was just missing the proper terminology word for this context. But thanks a lot for the enlightenment. I appreciate all the responses and educational feedback here immensely. -- kind regards, David Sommerseth _______________________________________________ dbus mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dbus