Я пытаюсь интерфейс UDisks2 с приложением Qt, и чтение пользовательского свойства приводит к сбою программы.
Для атрибутов SMART все в порядке (включая пользовательские свойства), но когда я пытаюсь прочитать свойство устройств 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
Кто-нибудь допускал такой случай? Я не думаю, что это вообще связано с моим кодом, так как результат тот же, если пользовательский тип не объявлен (сохраняя только содержимое главный функция).
Я не нашел правильного ответа для этого, но вот обходной путь: вызов Get
метод на интерфейсе org.freedesktop.DBus.Properties
и аннулирование результата вручную. Сложная часть была выяснение содержания результата (это QVariant содержащий QDBusVariant содержащий QDBusArgument)
Обновленный 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();
}