2015-02-05 69 views
2

我試圖將UDisks2與Qt應用程序接口,並讀取自定義屬性使程序崩潰。嘗試獲取自定義類型的DBus屬性時發生致命錯誤

對於SMART屬性,一切都OK了(包括custom properties),但是當我嘗試讀取RAID設備的屬性ActiveDevices我收到了Qt的致命錯誤和應用程序崩潰

下面是一個測試程序,它說明行爲:

#include <QApplication> 

#include <QDBusMetaType> 
#include <QDBusConnection> 
#include <QDBusInterface> 

#include <QDebug> 


//create the structure as defined in 
// http://udisks.freedesktop.org/docs/latest/gdbus-org.freedesktop.UDisks2.MDRaid.html#gdbus-property-org-freedesktop-UDisks2-MDRaid.ActiveDevices 
struct MDRaidMember { 
    QDBusObjectPath block; 
    qint32 slot; 
    QStringList state; 
    qint64 numReadErrors; 
    QVariantMap expansion; 
}; 
Q_DECLARE_METATYPE(MDRaidMember) 


//marshalling operator 
QDBusArgument &operator<<(QDBusArgument &argument, const MDRaidMember& raidMember) 
{ 
    argument.beginStructure(); 
    argument << raidMember.block; 
    argument << raidMember.slot; 
    argument << raidMember.state; 
    argument << raidMember.numReadErrors; 
    argument << raidMember.expansion; 
    argument.endStructure(); 
    return argument; 
} 


//unmarshall operator 
const QDBusArgument &operator>>(const QDBusArgument &argument, MDRaidMember& raidMember) 
{ 
    argument.beginStructure(); 
    argument >> raidMember.block; 
    argument >> raidMember.slot; 
    argument >> raidMember.state; 
    argument >> raidMember.numReadErrors; 
    argument >> raidMember.expansion; 
    argument.endStructure(); 
    return argument; 
} 



int main(int argc, char *argv[]) { 
    QApplication app(argc, argv); 

    //register the type, everything looks fine 
    qDebug() << qRegisterMetaType<MDRaidMember>("MDRaidMember"); 
    qDebug() << qDBusRegisterMetaType<MDRaidMember>(); 


    QDBusInterface iface("org.freedesktop.UDisks2", 
         "/org/freedesktop/UDisks2/mdraid/9aec6784_86ec37d4_8c1c6add_4dc9fe81", 
         "org.freedesktop.UDisks2.MDRaid", 
         QDBusConnection::systemBus()); 

    //read some properties 
    qDebug() << iface.property("UUID"); 
    qDebug() << iface.property("ActiveDevices"); //crash the test program! 

    return app.exec(); 
} 

執行此代碼生成以下輸出

1057 
1057 
QVariant(QString, "9aec6784:86ec37d4:8c1c6add:4dc9fe81") 
Cannot construct placeholder type QDBusRawType 
zsh: abort (core dumped) ./app/test_members 

任何人遇到這種情況?我沒有把它和我的代碼聯繫起來,因爲如果自定義類型沒有被聲明(只保留函數的內容),結果是一樣的。

+0

我面對完全相同的問題進行UDisks2。 – Orient 2017-11-16 06:08:24

回答

2

我沒有找到正確的答案,但這裏有一個解決方法:在接口org.freedesktop.DBus.Properties上調用Get方法並手動解組。最棘手的部分是斷定結果的內容(這是包含QDBusVariant含有QDBusArgument一個的QVariant

更新main功能:

//... 

int main(int argc, char *argv[]) { 
    QApplication app(argc, argv); 

    //register the type, everything looks fine 
    qDebug() << qRegisterMetaType<MDRaidMember>("MDRaidMember"); 
    qDebug() << qDBusRegisterMetaType<MDRaidMember>(); 


    QDBusInterface iface("org.freedesktop.UDisks2", 
        "/org/freedesktop/UDisks2/mdraid/9aec6784_86ec37d4_8c1c6add_4dc9fe81", 
        "org.freedesktop.DBus.Properties", 
        QDBusConnection::systemBus()); 

    QDBusMessage reply = iface.call("Get", "org.freedesktop.UDisks2.MDRaid", "ActiveDevices"); 
    QVariant v = reply.arguments().first(); 
    QDBusArgument arg = v.value<QDBusVariant>().variant().value<QDBusArgument>(); 

    QList<MDRaidMember> members; 
    arg.beginArray(); 
    while(!arg.atEnd()) { 
    MDRaidMember m; 
    arg >> m; 
    members << m; 
    } 

    qDebug() << members; 

    return app.exec(); 
} 
+0

有沒有無證的['qdbus_cast < T >(QVariant)'](https://github.com/openwebos/qt/blob/master/src/dbus/qdbusargument.h#L166)專門用於這些目的的重載。 – Orient 2017-11-16 07:00:20

相關問題