Details
-
Bug
-
Resolution: Invalid
-
Not Evaluated
-
None
-
5.0.0
-
None
-
Both x86 and ARM Qt5.0
Description
It seems the unmarshalling of a complex type (e.g. struct) from a QDBusVariant (dbus datatype 'v') is not working properly.
Some sample code follows.
D-Bus interface we are calling: We are interested in reading 'resultListWindow' 'v' variant, which returns a '(ddi)' struct (used for testing this bug).
<method name="RequestResultList"> <doc> <line>RequestResultList = This method gets the poi result list (e.g. after a Search/Scroll call)</line> </doc> <arg name="poiSearchHandle" type="u" direction="in"> <doc> <line>poiSearchHandle = poi search unique handle</line> </doc> </arg> <arg name="offset" type="q" direction="in"> <doc> <line>offset = starting offset of the newly requested list elements. If invalid (more that total list for instance) it starts from the begining.</line> </doc> </arg> <arg name="maxWindowSize" type="q" direction="in"> <doc> <line>maxWindowSize = maximum number of elements that should be returned as result</line> </doc> </arg> <arg name="attributes" type="as" direction="in"> <doc> <line>attributes = List of attributes name to retrieve. This is optional and the list could be empty.</line> </doc> </arg> <arg name="statusValue" type="q" direction="out"> <doc> <line>statusValue = enum(INVALID,NOT_STARTED,SEARCHING,FINISHED, ... )</line> </doc> </arg> <arg name="resultListSize" type="q" direction="out"> <doc> <line>resultListSize = Number of items of the results list</line> </doc> </arg> <arg name="resultListWindow" type="v" direction="out"> <doc> <line>For testing purposes returns '(ddi)' in the variant.</line> </doc> </arg> <error name="org.genivi.poiservice.poiSearch.Error.HandleNotAvailable"> <doc> <line>This error is generated if an application tries to use a poi search unique handle that is not available or not valid</line> </doc> </error> <error name="org.genivi.poiservice.poiSearch.Error.InvalidPoiAttribute"> <doc> <line>This error is generated if an application tries to get one or more invalid poi attributes.</line> </doc> </error> </method>
Declaration of custom struct conforming to '(ddi)' signature:
namespace poiservice { namespace poisearch { struct SLocation { double mLat; double mLon; qint32 mAlt; SLocation() : mLat(0.0), mLon(0.0), mAlt(0) { } bool operator==(const SLocation &other) const { return (mLat == other.mLat) && (mLon == other.mLon) && (mAlt == other.mAlt); } }; QDBusArgument& operator<<(QDBusArgument& arg, const SLocation& location); const QDBusArgument& operator>>(const QDBusArgument& arg, SLocation& location); } } // namespace poiservice::poisearch typedef QList<QString> TStringList; Q_DECLARE_METATYPE(poiservice::poisearch::SLocation)
Marshall operator for custom struct:
QDBusArgument& poiservice::poisearch::operator<<(QDBusArgument& arg, const SLocation& location) { arg.beginStructure(); arg << location.mLat << location.mLon << location.mAlt; arg.endStructure(); return arg; } const QDBusArgument& poiservice::poisearch::operator>>(const QDBusArgument& arg, SLocation& location) { arg.beginStructure(); arg >> location.mLat >> location.mLon >> location.mAlt; arg.endStructure(); return arg; }
Registration of DBus metatypes:
int metaTypeId = qDBusRegisterMetaType<SLocation>();
Proxy generated by qdbusxml2cpp:
inline QDBusPendingReply<ushort, ushort, QDBusVariant> RequestResultList(uint poiSearchHandle, ushort offset, ushort maxWindowSize, const QStringList &attributes) { QList<QVariant> argumentList; argumentList << QVariant::fromValue(poiSearchHandle) << QVariant::fromValue(offset) << QVariant::fromValue(maxWindowSize) << QVariant::fromValue(attributes); return asyncCallWithArgumentList(QLatin1String("RequestResultList"), argumentList); }
Our wrapper code calling the proxy:
void CPOIServicePOISearchWrapper::sltRequestResultList(quint32 poiSearchHandle, quint16 offset, quint16 maxWindowSize, TStringList attributes, quint16& outStatusValue, quint16& outResultListSize, QDBusVariant& outResultListWindow) { QDBusPendingReply<ushort,ushort,QDBusVariant> reply = mProxy->RequestResultList(poiSearchHandle, offset, maxWindowSize, attributes); reply.waitForFinished(); if (reply.isValid()) { outStatusValue = reply.argumentAt<0>(); outResultListSize = reply.argumentAt<1>(); outResultListWindow = reply.argumentAt<2>(); } else { QString exceptionMessage = QString::number(reply.error().type()) + " - " + reply.error().name() + " - " + reply.error().message(); throw std::runtime_error(exceptionMessage.toStdString()); } }
Our code calling the wrapper: I have added some comments explaining what is going wrong.
quint16 outStatusValue; quint16 outResultSize; QDBusVariant outVariant; QList<QString> stringList; // example call, we are interested in 'outVariant' mGeniviPoiSearch->sltRequestResultList(1, 0, 1000, stringList, outStatusValue, outResultSize, outVariant); QVariant variant = outVariant.variant(); qDebug() << "Variant type: " << variant.type(); // output of the above line: Variant type: QVariant::QPaintBufferCacheEntry int userType = variant.userType(); qDebug() << "Variant usertype: " << userType; // output of the above line: Variant usertype: 1028 if (variant.canConvert<poiservice::poisearch::SLocation>()) { qDebug() << "CAN convert to SLocation"; } else { // this code is executed, conversion fails. qDebug() << "Can NOT convert to SLocation"; } // also, this results in 'empty' struct: poiservice::poisearch::SLocation location = variant.value<poiservice::poisearch::SLocation>();
So it seems unmarshalling of complex types in DBus 'v' variants not working.
The resulting value from variant.type() is QPaintBufferCacheEntry (see comments in last code block).