2010-11-23 82 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());