2013年10月11日 星期五

QtDBus Proxy 訪問遠端物件與回傳值 demarshall

在之前的文章[1]裡,我提到QtDBus在叫用DBus上的方法時,對輸入參數和輸出參數的資料型態必須做marshall和demarshall,而且有點不太容易。有些人會説,你只使用QDBusMessage來叫用方法以及接收回傳值,這不是Qt建議的作法!用QDBusMessage來做太低階了,所以參數的型態才要轉換的那麼辛苦。

因此,我要使用Qt建議的Proxy類别[2]做法來試試看,是不是比較容易一些。首先,之前討讑提到的輸入參數資料型態為object path時,必須自己使用QVariant::fromValue(object_path)將資料填入參數列中。使用Proxy類别做法,在使用qdbusxml2cpp工具産生需要的proxy類别後,我們可以很直觀的使用以下語法,將資料型態為QDBusObjectPath的變數,直接送入輸入參數資料型態為object path的方法中。
    proxy.Method(object_path);
真是太好了,這様大家都輕鬆許多。
看一下qdbusxml2cpp工具産生的類别proxy程式,可以看到如下一段程式,原來是這個proxy類别幫我自動做了同様的轉換工作。
    inline QDBusPendingReply<> Method(const QDBusObjectPath &device)
    {
        QList<QVariant> argumentList;
        argumentList << QVariant::fromValue(device);
        return asyncCallWithArgumentList(QLatin1String("Method"), argumentList);
    }
其實不管Qt是如何做到的,只要能減輕我們的工作就好了。
那麼複雜的參數型態呢?是不是也可以幫我們一點忙呢?
我們來看一下之前討讑的字典中有矩陣的問題,許多的DBus方法中,特别是取得屬性的方法,通常是叫做GetProperties(),它的回傳值都是一個字典(a{sv}),而且其中有一些值,其實是個矩陣。一様的問題,用Proxy類别的作法可以取得字典的回傳值。但我要取得其中一個值的矩陣,要如何做呢?如下片斷程式,利用qDebug()來看一下回傳值的内容。
    QDBusPendingReply<QVariantMap> reply = proxy.GetProperties();
    reply.waitForFinished();
    qDebug() << reply.value();
結果是:
QMap(("Address", QVariant(QString, "00:1A:7D:xx:xx:xx") ) ( "Class" ,  QVariant(uint, 0) ) ( "XXXX" ,  QVariant(QDBusArgument, ) ) ( "Discoverable" ,  QVariant(bool, false) ) ( "DiscoverableTimeout" ,  QVariant(uint, 0) ) ( "Discovering" ,  QVariant(bool, false) ) ( "Name" ,  QVariant(QString, "ubuntu-x") ) ( "Pairable" ,  QVariant(bool, true) ) ( "PairableTimeout" ,  QVariant(uint, 0) ) ( "Powered" ,  QVariant(bool, true) ) ( "UUIDs" ,  QVariant(QStringList, ("00001000-0000-1000-8000-00805f9bxxxx", "00001001-0000-1000-8000-00805f9bxxxx", "0000112d-0000-1000-8000-00805f9xxxxb", "00001112-0000-1000-8000-00805f9xxxxb", "0000111f-0000-1000-8000-00805f9xxxxb") ) ) ) 
重點是,我們要的Key為"XXXX"的屬性,其值部份的資料型態仍然為QVariant(QDBusArgument),也就是説,我們還是要自行做轉型的工作。而轉型的方法,目前我覺得就是用前文討讑的方法,由QDBusArgument的成員函數beginArray(), atEnd(), asVariant()來完成。除此之外,不知道是不是有其他更好的方法了!


參考來源:
[1] 小白和小叮叮, QtDBus marshall and demarshall, 2013/10/8
[2] wwang, D-BUS和QT4, 2010/10/27
張貼留言