2012-10-11 33 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; 

}