returning properties

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Oct 21 03:00:50 PDT 2011


On Thu, 20 Oct 2011 at 19:54:44 -0500, Mike Gorse wrote:
> I just noticed that some code I wrote using gdbus is returning a
> property as a struct inside a variant, even when there is only one
> piece of data being returned.

Method calls in GDBus always return a GVariant struct (you can call it a
tuple if you prefer) containing the actual returns from the method, to make
the calling convention consistent when you call a method with 0, 1 or 2+
returns:

    ReturnNothing -> ()                  struct "()" with 0 elements
    ReturnInt -> (1,)                    struct "(i)" with 1 element
    ReturnTwoInts -> (1, 2)              struct "(ii)" with 2 elements
    ReturnManyInts -> (1, 2, ..., 42)    struct "(ii...i)" with 42 elements

This extra level of struct isn't visible "on the wire" - conceptually, it's
the body of the D-Bus message, rather than an explicit struct.

Compare with Python (and dbus-python, which copies Python conventions), which
is uncomfortably "do what I mean" about multiple returns:

    return_nothing -> None               NoneType
    return_int -> 1                      int
    return_two_ints -> (1, 2)            tuple with 2 elements
    return_many_ints -> (1, 2, ..., 42)  tuple with 42 elements

Is the method-return "fake struct" the extra level of nesting you're seeing,
or is there another?

> When reading properties, do
> bindings generally expect a struct within a variant, or is a single
> piece of data generally encoded directly into a variant, or is
> either approach generally accepted?

At the D-Bus level, Get("...MyInterface", "MyStringProperty") should return
a variant containing a string. No structs involved.

In GDBus this will get wrapped in the "fake struct" that's used to encode
multiple returns, so these two calls will both return the same thing, namely
a GVariant of type "(v)", containing a GVariant of type "v", containing
a string:

    g_dbus_connection_call_sync (conn, bus_name, path, "...Properties",
                                 "Get",
				 g_variant_new ("(ss)", "...MyInterface",
				                "MyStringProperty"),
                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL)

    g_variant_new_parsed ("(<'my string value'>)")

Hope this helps,
    S


More information about the dbus mailing list