2010-11-23 90 views
14

我想深入了解Qt开发中的Google协议缓冲区,但是我很难弄清楚如何最好地融入它们。Qt + protobuf,类型?

最终,我想使用协议缓冲区发送QUdpSocketQTcpSocket

在协议缓冲区message到通过套接字(QByteArray)发送数据然后再在另一端再次返回的最佳方法是什么?

Person person; // a protobuf object 
person.set_id(123); 
person.set_name("Bob"); 
person.set_email("[email protected]"); 

std::ostringstream out; 
person.SerializeToOstream(&out); 
QByteArray byteArray(out.str().c_str()); 
sendSerializedPersonOverQTcpSocket(byteArray); 

回读一个protobuf的对象从QByteArray

回答

12

从protobuf的对象创建QByteArray

QByteArray byteArray = readSerializedPersonFromQTcpSocket(); 
Person person; 
if (!person.ParseFromArray(byteArray, byteArray.size())) { 
    std::cerr << "Failed to parse person.pb." << std::endl; 
} 
+4

没有错,但你需要一些方法来确定消息另一方面。另外,您需要确定数据的长度。 Protobuf不会在内部完成这些任务。此外,流输出版本是格式化程序中速度最慢的 - 矢量/数组输出速度更快。 – 2010-11-23 07:15:15

+0

我一直在尝试使用`SerializeToArray`方法,但无法弄清楚如何转换为`QByteArray`。你能举一个例子吗? – Jay 2010-11-23 15:30:39

3

@詹姆斯:你可以使用ParseFromArray(),例如,如下:(请注意,ParseFromArray()仅适用于libs的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()) 
     { 
      //... 
     } 
    } 
} 
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:OK,现在我知道它是如何工作的:如果有序列化\ 0字符前两种方式是错误的 - 一切后,它便失去。要纠正一个可以写:

QByteArray byteArray(person.SerializeAsString().c_str(), person.ByteSize()); 
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());