Question

While using the qdbusxml2cpp program to convert the following xml to a Qt Class, I am getting this error:

qdbusxml2cpp -c ObjectManager -a ObjectManager:ObjectManager.cpp xml/object_manager.xml 
Got unknown type `a{oa{sa{sv}}}'
You should add <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="<type>"/> to the XML description

D-Feet description:

enter image description here

XML:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/>
</method></interface><interface name="org.freedesktop.DBus.ObjectManager"><method name="GetManagedObjects"><arg name="objects" type="a{oa{sa{sv}}}" direction="out"/>
</method><signal name="InterfacesAdded"><arg name="object" type="o"/>
<arg name="interfaces" type="a{sa{sv}}"/>
</signal>
<signal name="InterfacesRemoved"><arg name="object" type="o"/>
<arg name="interfaces" type="as"/>
</signal>
</interface><node name="org"/></node>

From this website ( http://techbase.kde.org/Development/Tutorials/D-Bus/CustomTypes ) I understand that I need to add an annotation to the XML for the tool to work properly.

Here is what I have so far:

a{oa{sa{sv}}}

https://alteeve.ca/w/List_of_DBus_data_types
o == A UTF-8 string whose value is a valid DBus object path.

array { object_path array { string array { string variant } } }

<arg name="customdata" type="a{sv}" direction="in" />
QVariantMap in the arguments (type "a{sv}")
QMap<QString, QVariant>

However, I'm not sure what the annotation should be for a{oa{sa{sv}}}, can someone please help me understand? Thanks!

Was it helpful?

Solution

openSUSE imagewriter is a GPL licensed project which contains an example of how to do this.
(Relevant files: udisks2_interface.*)


a{sv} is a dict of string:variant pairs.
QVariantMap would fit this signature.

a{sa{sv}} is a dict of string:a{sv} pairs.
QMap<QString, QVariantMap> would fit this signature.

a{oa{sa{sv}}} is a dict of objectpath:a{sa{sv}} pairs.
QMap<QDBusObjectPath, QMap<QString, QVariantMap>> would fit this signature.

We should hide those angle-brackets behind some typedefs in a header file:

typedef QMap<QString, QVariantMap> InterfaceList;
typedef QMap<QDBusObjectPath, InterfaceList> ManagedObjectList;

Then declare their QMetaTypes in the same header file:

Q_DECLARE_METATYPE(InterfaceList)
Q_DECLARE_METATYPE(ManagedObjectList)

Then register them with the Qt metatype system at runtime:

qDBusRegisterMetaType<InterfaceList>();
qDBusRegisterMetaType<ManagedObjectList>();

Then we can annotate the XML:

<method name="GetManagedObjects">
  <arg type="a{oa{sa{sv}}}" name="objects" direction="out" />
  <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ManagedObjectList"/>
</method>
<signal name="InterfacesAdded">
  <arg type="o" name="object"/>
  <arg type="a{sa{sv}}" name="interfaces" />
  <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="InterfaceList"/>
</signal>

OTHER TIPS

I had the same problem with the newer version (Qt5.12). I didn't want to modify the code generated, and found out how to generate this code properly.
qdbusxml2cpp wasn't sure how to deal with dictionary signatures. My solution is to add the annotations directly with the Qt types. as in this, for
"a{oa{sa{sv}}}" -> QMap<QDBusObjectPath, QMap<QString, QVariantMap> >

<method name="GetManagedObjects">
  <arg type="a{oa{sa{sv}}}" name="object_paths_interfaces_and_properties" direction="out"/>
  <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QMap&lt;QDBusObjectPath,QMap&lt;QString,QVariantMap&gt;&gt;"/>
</method>

With &lt fot < and &gt fot > . Then the code generated is correct.

Hope this will help someone, one day... after 8 years

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top