我想通过Qt DBUS API发送一个自定义c++类。我已经使用protoc编译器从.proto文件创建了这个类,并将它们添加到我在QtCreator中的项目中。现在我想验证我是否可以通过dbusneneneba API将自定义类作为QVariant发送。我有一个接收器和发送器程序,可以发送一个简单的测试字符串,这样Dbus就可以工作了。在将协议缓冲区类添加为元类型后,我在发送它时遇到问题。
我的test.proto文件只包含int:
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;
}
Main看起来像这样:
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";
}
这是Sender程序的输出:
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
为什么编组函数似乎被调用了两次?为什么第二个调用似乎包括我的协议缓冲区的3个属性的有效值2,3,4,但第一个调用都是0?接收器似乎只看到All 0,并且从未接收到具有有效值的协议缓冲区对象。
我的编组代码有问题吗?还会发生什么?
要实现此操作,请实现如下运算符:
// 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;
}