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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.