我想在Qt开发中深入研究Google的协议缓冲区,但我无法弄清楚如何最好地合并它们。
最终,我希望使用协议缓冲区发送QUdpSocket
和QTcpSocket
。
在协议缓冲区message
之间切换到通过套接字(QByteArray
)发送数据然后再返回另一端的最佳方法是什么?
答案 0 :(得分:12)
从protobuf对象创建QByteArray
:
Person person; // a protobuf object
person.set_id(123);
person.set_name("Bob");
person.set_email("bob@example.com");
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);
从QByteArray
:
QByteArray byteArray = readSerializedPersonFromQTcpSocket();
Person person;
if (!person.ParseFromArray(byteArray, byteArray.size())) {
std::cerr << "Failed to parse person.pb." << std::endl;
}
答案 1 :(得分:6)
而不是:
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
你也可以写:
QByteArray byteArray(person.SerializeAsString().c_str());
编辑:上面两个给出相同的结果,但我不确定它是否正确。这个似乎更好:
QByteArray byteArray(QString::fromStdString(person.SerializeAsString()));
EDIT2:好的,现在我知道它是如何工作的:前两种方法是错误的,如果序列化中有\ 0个字符 - 它之后的所有内容都会丢失。要纠正它,可以写:
QByteArray byteArray(person.SerializeAsString().c_str(), person.ByteSize());
答案 2 :(得分:4)
使用下面的代码非常危险
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);
您可以在In protobuf-c, can optional uint32 variable have value 0
找到一个很好的解释从protobuf消息创建QByteArray的正确方法是
QByteArray byteArray;
byteArray.resize(message.ByteSize());
message.SerializeToArray(byteArray.data(), byteArray.size());
答案 3 :(得分:3)
@James:您可以使用ParseFromArray()
,例如,如下所示:(请注意,ParseFromArray()
仅适用于lib的proto-buf-lite版本。)
void convertQByteArrayToUser(QByteArray& aByteArray)
{
com::your::name_space::User user;
if(!user.ParseFromArray(aByteArray.data(), aByteArray.size()))
{
//could not parse
}
else { //yayyyyy
if(user.has_userid())
{
//...
}
}
}