2017-07-30 3212 views
0

您好我有一個簡單的例子addressbook.proto我使用python中的protobuf SerailizeToString()函數進行序列化。這是代碼。使用SerializeToString()和ParseFromString()函數將Python ProtoBuf轉換爲C++ ProtoBuf

import address_pb2 

person = address_pb2.Person() 
person.id = 1234 
person.name = "John Doe" 
person.email = "[email protected]" 
phone = person.phones.add() 
phone.number = "555-4321" 
phone.type = address_pb2.Person.HOME 

print(person.SerializeToString()) 

哪裏address_pb2是我從protobuf的編譯器生成的文件。請注意,該示例是從protoBuf教程中複製的。這給了我下面的字符串。

b'\n\x08John Doe\x10\xd2\t\x1a\[email protected]"\x0c\n\x08555-4321\x10\x01' 

現在我想將這個字符串導入到C++ protobuf中。爲此我寫了下面的代碼。

#include <iostream> 
#include <fstream> 
#include <string> 
#include "address.pb.h" 
using namespace std; 

int main(int argc, char* argv[]) { 
    GOOGLE_PROTOBUF_VERIFY_VERSION; 


    tutorial::AddressBook address_book; 
    string data = "\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""[email protected]\"\x0c""\n\x08""555-4321\x10""\x01"""; 
    if(address_book.ParseFromString(data)){ 
    cout<<"working"<< endl; 
    } 
    else{ 
    cout<<"not working" << endl; 
    } 


    // Optional: Delete all global objects allocated by libprotobuf. 
    google::protobuf::ShutdownProtobufLibrary(); 

    return 0; 
} 

在這裏,我只是試圖導入使用ParseFromString()溫控功能的腳本,但是,這並不工作,我不知道它是如何工作的,因爲我已經因爲現在很長一段時間停留在此。

我試着改變二進制適合C++版本,但仍然不知道,如果我在正確的道路上或沒有。

我該如何做到這一點?有人有線索嗎?

回答

1

在Python中,您正在序列化一個Person對象。在C++中,您正試圖解析一個AddressBook對象。你需要在兩端使用相同的類型。

(請注意,protobuf的並不能保證它會檢測到這些錯誤。有時,當你分析一個消息作爲錯誤的類型,解析看似成功,但內容將是垃圾。)


有你的代碼的另一個問題出現這種情況並非是在這種特殊情況下的一個問題,但不會在一般的工作:

string data = "\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""[email protected]\"\x0c""\n\x08""555-4321\x10""\x01"""; 

這條線將不如果字符串有任何NUL字節,即工作「 \ X00' 。如果是這樣,該字節將被解釋爲字符串的結尾。爲了避免這個問題,你需要指定數據的長度,如:

string data("\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""[email protected]\"\x0c""\n\x08""555-4321\x10""\x01""", 45); 
+0

與解析'Person'對象使它工作。你在數據字符串中傳遞的45是str.len? – Mj1992

+0

我剛剛遇到了同樣的問題,就像你在關於'\ x00'的答案的第二部分中提到的一樣。我試圖通過傳遞不解析字符串的字符串長度來做同樣的事情。你能幫我解決嗎? – Mj1992

+0

是的,45是以字節爲單位的字符串長度。你可以使用'len()'從python端獲得它。請注意,如果您想在C++端使用'strlen()'來獲取長度,那麼這將不起作用,因爲它只會計數到第一個'\ x00'。 –