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

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 ++版本,但是仍然不知道我是否在正确的路径上。

我该如何实现?有人有线索吗?

最佳答案

在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);

关于python - 使用SerializeToString()和ParseFromString()函数将Python ProtoBuf转换为C++ ProtoBuf,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45403854/

10-13 07:05