[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