[Development] D-Bus and (de-)marshalling of complex types (QDBusArgument)

Thiago Macieira thiago.macieira at intel.com
Thu Apr 26 12:19:14 CEST 2012


On quinta-feira, 26 de abril de 2012 11.49.02, Alberto Mardegan wrote:
> Hi all!
>  The current QtDBus implementation automatically marshals only the
> basic D-Bus types, and puts all the complex types into a QDBusArgument.

Yeah, I called it the "Pattern Buffer" when I wrote that trick in 2006. Because 
I like Star Trek and I wanted a codename, since other technologies had them 
(Scribe, Interview, etc.).

> I've found a reason for this behaviour here:
> http://permalink.gmane.org/gmane.comp.freedesktop.dbus/5920
> 
> However, unless I'm missing something, this only explains why we cannot
> marshal for aggregate types (structures); we should still be able to
> marshal array and dictionary types.

Not exactly... there are two reasons why this can't be done.

The first is that QtDBus doesn't choose a container type for arrays and 
dictionaries. It works just fine with QList, QVector, QLinkedList, std::list, 
std::vector, etc. for arrays, as well as QHash, QMap, std::map, std::hash_map, 
std::unordered_map, etc. for dictionaries. It's up to the user of QtDBus to 
choose which one they want to use.

The second is that each container is a different C++ type. QList<int> is wholly 
different from QList<uint> from C++'s perspective and from ours, even though 
they happen to have the exact same memory layout (which isn't true for other, 
more different types). We'd have to register as metatypes every single QList of 
the basic types, plus every single QMap of the permutations of possible basic 
type-dictionaries in D-Bus.

So even if we don't include more complex types like arrays of arrays, arrays 
of dictionaries, dictionaries of arrays, we'd have 15 QList-types (including 
QStringList, QVariantList and QByteArray), 12 * 14 QMap types (including 
QVariantMap). I'm not going to register 179 types at QtDBus start up -- that's 
twice as many types than a typical Qt application has today, including the 
builtins!

Still, QtDBus *does* register the basic QList types for convenience. And I 
suppose we can add some convenience elsewhere too. I've seen many projects 
that need to force an inclusion of a Q_DECLARE_METATYPE(QList<int>) to their 
generated C++ sources.

> Regardless of all this, I'm now facing a problem with serializing a
> QDBusArgument into a QDataStream: QDBusArgument::currentType() can tell
> me that the argument is a map, but doesn't tell me the signature of the
> keys and values. Therefore, there seems to be no way I can parse a map
> out of a QDBusArgument, without knowing its signature. :-(
> 
> Should we have a QDBusArgument::signature() method?

It's there: QDBusArgument::currentSignature()

For whatever reason that I can't remember right now, the method is marked 
\internal in the documentation.

Depending on the context, you don't need to know the signature and 
currentType() might be enough. You can do a beginMap() and you'll have a type 
of MapEntryType. Then you beginMapEntry() and you should have a BasicType -- 
which is always demarshalled. After you demarshall that, you'll have any type 
again.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
     Intel Sweden AB - Registration Number: 556189-6027
     Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20120426/a5217fcf/attachment.sig>


More information about the Development mailing list