将Python ProtoBuf转换为C++;ProtoBuf使用SerializeToString()和ParseFromString()函数

将Python ProtoBuf转换为C++;ProtoBuf使用SerializeToString()和ParseFromString()函数,python,c++,protocol-buffers,Python,C++,Protocol Buffers,大家好,我有一个简单的addressbook.proto示例,我正在使用python中的protobufSerailizeToString()函数进行序列化。这是密码 import address_pb2 person = address_pb2.Person() person.id = 1234 person.name = "John Doe" person.email = "jdoe@example.com" phone = person.phones.add() phone.number

大家好,我有一个简单的
addressbook.proto
示例,我正在使用
python
中的protobuf
SerailizeToString()
函数进行序列化。这是密码

import address_pb2

person = address_pb2.Person()
person.id = 1234
person.name = "John Doe"
person.email = "jdoe@example.com"
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\x10jdoe@example.com"\x0c\n\x08555-4321\x10\x01'
现在我想把这个字符串导入C++原语BUFF。为此,我编写了以下代码

#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""jdoe@example.com\"\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;
}
#包括
#包括
#包括
#包括“address.pb.h”
使用名称空间std;
int main(int argc,char*argv[]){
谷歌协议验证版本;
教程::地址簿地址簿;
字符串数据=“\n\x08”“John Doe\x10”“\xd2”“\t\x1a”“\x10”jdoe@example.com\“\x0c”“\n\x08”“555-4321\x10”“\x01”“”;
if(地址簿.ParseFromString(数据)){

Python中的CUT

,您正在序列化<代码>人>代码>对象。在C++中,您试图解析<代码>地址簿< /COD>对象。您需要在两端使用相同的类型。

(请注意,protobuf并不保证它会检测到这些错误。有时,当您将消息解析为错误类型时,解析似乎会成功,但内容将是垃圾。)


您的代码还有一个问题,在这种特定情况下,它恰好不是问题,但通常不起作用:

string data = "\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""jdoe@example.com\"\x0c""\n\x08""555-4321\x10""\x01""";
如果字符串有任何NUL字节,即“\x00”,则此行将不起作用。如果是这样,则该字节将被解释为字符串的结尾。为避免此问题,您需要指定数据的长度,如:

string data("\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""jdoe@example.com\"\x0c""\n\x08""555-4321\x10""\x01""", 45);

使用
Person
对象进行解析使其工作。您在数据字符串中传递的45,是str.len吗?我刚刚遇到了与您在回答的第二部分中提到的关于
\x00
的问题相同的问题。我试图通过传递不解析字符串的字符串长度来执行与您所说的相同的操作。您能帮我解决吗?是的,是的45是字节长度的字符串。你可以通过使用python边获得它,使用<代码> Le()/<代码>。注意,如果你试图在C++侧使用<代码> String()/<代码>来获取长度,那将不起作用,因为它只会计数到第一个< >代码> \x00 < /COD>。