Round-trip type marshalling (was: Announcing new version of the Qt4 bindings)

Thiago Macieira thiago.macieira at trolltech.com
Tue Feb 14 02:30:22 PST 2006


Havoc Pennington wrote:
>> Depending on how the call is handled by the application, the Qt
>> bindings will lose information and not reply 1:1.
>>
>> If the idea is to just round-trip, 1:1 matching is done already (or so
>> I believe).
>
>I may not be clear, what I mean by "round trip" is to demarshal to
>native types and then marshal the same values again as dbus types.

And, as I said, it depends on what the application does with those types.

The native types, in this case, are just a QVariant. And QVariant has some 
limitations:
- it can't distinguish BYTE and INT16 from INT32
- it can't distinguish UINT16 from UINT32
- dictionary entry keys are converted to strings and the values are stored 
as QVariant
- structs and arrays are stored as simple lists, which means we can't tell 
a struct and an array apart (arrays of simple types apart from a 
homogeneous struct; array of variant apart from a struct)

This means that, given a QVariant without context, we've lost its original 
type. So a round-trip inside Qt going through QVariant will make the 
message fuzzy, because the marshaller will have to guess what type was 
intended. That is, upon seeing a QVariant of type "Int", it'll always 
send an INT32, and all dictionaries would be "a{sv}".

However, given context, the original types are restored. So, if all we're 
doing is "ping-pong", 1:1 type matching is preserved. That is done by 
telling the QDBusMessage reply what type signature it has to be.

This works for method calls to, so we can be sure of calling the right 
function on a remote service.

>There are a couple things this test would be designed to do:
> - be sure there's some way to marshal each dbus type from a given
>   binding; otherwise some interfaces would not be usable from the
>   binding

The solution we currently have is to not encode the desired type 
information in the type, but in the method call. This is more or less 
what DCOP did: to call a function, you had to tell it what the arguments 
were.

For instance, if we have this code:
  dbus_int16_t value = -1;
  iface.call("mymethod", value);
then "value" will be sent as INT32.

If, however, we write it like this:
  dbus_int16_t value = -1;
  iface.call("mymethod.n", value);
it'll be properly sent as INT16.

The same works for arrays and structs:
  QVariantList list; list << 1 << 2 << 3 << (short)-1;
  iface.call("mymethod", list);		// will send as "ai"
  iface.call("mymethod.an", list); 	// will send as "an"
  iface.call("mymethod.(iinn)", list); 	// will send as "(iinn)"
  iface.call("mymethod.s", list);	// will not send

> - be sure the binding deals with all the tricky cases
>   (zero-length arrays, structs with arrays in them, arrays of struct,
>    etc.) 
> - the test function I mentioned returns all the various 
>   combinations of types

I'll have to try, but it's supposed to work.

>A couple fixes for that, still preserving the purpose of the test:
> - for the test suite only, keep lookaside/meta information on the
>   exact dbus type that was demarshaled, for use on remarshal

That's what we'd do.

> - "fuzzy equality" for test success (allow an int16 that gets
>   remarshaled as int32 to pass)
>
>Just some thoughts, nothing Qt-specific, this would be cool for the
>other bindings too IMO.

-- 
Thiago José Macieira - thiago.macieira AT trolltech.com
Trolltech AS - Sandakerveien 116, NO-0402 Oslo, Norway
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/dbus/attachments/20060214/1db5ffab/attachment.pgp


More information about the dbus mailing list