2012-10-11 30 views
1

我想通過Qt DBUS API發送一個自定義C++類。我使用protoc編譯器從.proto文件創建了類,並將它們添加到QtCreator中的項目中。現在我想驗證我可以通過dbus API將定製類作爲QVariant發送。我有一個接收器和發件人程序,可以發送一個簡單的測試字符串,以便Dbus工作。在將它添加爲元類型後,我無法發送協議緩衝區類。qdbus和自定義類型的編組

我的測試.proto文件只包含整型:

message MyData { 
    required int32 name = 1; 
    required int32 id = 2; 
    optional int32 email = 3; 
} 

議定書緩衝區類的頭文件我補充說:

#include <QMetaType> 
#include <QDBusMetaType> 
... 
friend QDBusArgument &operator<<(QDBusArgument &argument, const MyData &dataToWrite); 
friend const QDBusArgument &operator>>(const QDBusArgument &argument, MyData &dataToWrite); 
... 
Q_DECLARE_METATYPE(MyData) 

而要我加了協議緩衝區類實現文件:

#include <QDebug> 
... 
#include <QMetaType> 
#include <QDBusMetaType> 

// Marshall the MyData data into a D-Bus argument 
QDBusArgument &operator<<(QDBusArgument &argument, const MyData &dataToWrite) 
{ 

    qDebug() << "OPERATOR<<"; 

    argument.beginStructure(); 

    // Break out the various properties of dataToWrite protocol buffer 
    int name = dataToWrite.name(); 
    int id = dataToWrite.id(); 
    int email = dataToWrite.email(); 
    qDebug() << name; 
    qDebug() << id; 
    qDebug() << email; 

    argument << name; 
    argument << id; 
    argument << email; 
    argument.endStructure(); 
    return argument; 

} 

// Retrieve the MyData data from the D-Bus argument 
const QDBusArgument &operator>>(const QDBusArgument &argument, MyData &dataToWrite) 
{ 

    qDebug() << "OPERATOR>>"; 

    argument.beginStructure(); 

    // Break out the various properties of dataToWrite protocol buffer 
    int name = dataToWrite.name(); 
    int id = dataToWrite.id(); 
    int email = dataToWrite.email(); 
    qDebug() << name; 
    qDebug() << id; 
    qDebug() << email; 

    argument >> name; 
    argument >> id; 
    argument >> email; 
    argument.endStructure(); 
    return argument; 

} 

主要看起來像這樣:

QCoreApplication a(argc, argv); 

    dbussender* client = new dbussender("com.one.two.three.nvram", "/dbusReadWriteNvRam", QDBusConnection::sessionBus(), 0); 

    // Create a protocol buffer class and provide its properties with values 
    MyData dataToWrite; 
    dataToWrite.set_name(2); 
    dataToWrite.set_id(3); 
    dataToWrite.set_email(4); 

    QString command3 = "Contacting Protobuf Receiver and calling WRITENVRAM..."; 
    QString response3 = client->writeNVRam(dataToWrite); 

    std::cout << "Command: " << command3.toStdString() << std::endl; 
    std::cout << "Response: " << response3.toStdString() << std::endl; 

我dbussender類調用遠程函數是這樣的:

inline QDBusPendingReply<QString> writeNVRam(MyData dataToWrite) 
    { 

     qDebug() << "Sending " << dataToWrite.name(); 
     qDebug() << "Sending " << dataToWrite.id(); 
     qDebug() << "Sending " << dataToWrite.email(); 

     QList<QVariant> argumentList; 
     argumentList << QVariant::fromValue<MyData>(dataToWrite); 
     return asyncCallWithArgumentList(QLatin1String("writeNVRam"), argumentList); 
    } 

最終在我的接收程序,這個函數被調用,但總是返回0:

// Write NVRAM 
QString dbusReadWriteNvRam::writeNVRam(MyData dataToWrite) { 

    qDebug() << "WRITE NVRAM COMMAND CALLED"; 

    qDebug() << "Unpacking: " << dataToWrite.name(); 
    qDebug() << "Unpacking: " << dataToWrite.id(); 
    qDebug() << "Unpacking: " << dataToWrite.email(); 

    return "HELLO CLASS"; 

} 

這裏的輸出發件人程序:

Sending 2 
Sending 3 
Sending 4 
OPERATOR<< 
0 
0 
0 
OPERATOR<< 
2 
3 
4 
Command: Contacting Protobuf Receiver and calling WRITENVRAM... 
Response: HELLO CLASS 

這裏是接收器程序的輸出:

OPERATOR<< 
0 
0 
0 
OPERATOR>> 
0 
0 
0 
WRITE NVRAM COMMAND CALLED 
Unpacking: 0 
Unpacking: 0 
Unpacking: 0 

爲什麼看起來編組函數被調用兩次?第二次調用似乎包含2,3,4協議緩衝區的有效值,但第一次調用都是0? Receiver似乎只能看到All 0,並且從不接收具有有效值的協議緩衝區對象。

我的編組代碼有問題嗎?還有什麼可以繼續?

+0

我也看到了同樣的事情,編組由客戶端調用兩次。在服務器端,首先調用然後調用解組。我也很困惑。我也提出了一個問題 - http://stackoverflow.com/questions/21939006/why-marshalling-is-done-twice-by-the-client-in-qdbus-dbus。你爲什麼會發生這樣的運氣?但有趣的是,我的代碼工作正常。 –

回答

1

爲了使這項工作,實現運營商,像這樣:

// PROTOBUF-MODIFICATION-DBUS 
// Marshall the companyData data into a D-Bus argument 
QDBusArgument &operator<<(QDBusArgument &argument, const companyData &dataToWrite) 
{ 

    argument.beginStructure(); 

    // Break out the various properties of dataToWrite protocol buffer 
    int name = dataToWrite.name(); 
    int id = dataToWrite.id(); 
    int email = dataToWrite.email(); 
    argument << name; 
    argument << id; 
    argument << email; 
    argument.endStructure(); 
    return argument; 

} 

// PROTOBUF-MODIFICATION-DBUS 
// Retrieve the companyData data from the D-Bus argument 
const QDBusArgument &operator>>(const QDBusArgument &argument, companyData &dataToWrite) 
{ 

    int name, id, email; 

    argument.beginStructure(); 
    argument >> name; 
    argument >> id; 
    argument >> email; 
    argument.endStructure(); 
    dataToWrite.set_name(name); 
    dataToWrite.set_id(id); 
    dataToWrite.set_email(email); 
    return argument; 

}