简体   繁体   English

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

[英]Converting Python ProtoBuf to C++ ProtoBuf using SerializeToString() and ParseFromString() functions

Hi I've a simple example of addressbook.proto I am serializing using the protobuf SerailizeToString() function in python . 嗨,我有一个addressbook.proto的简单示例,我正在使用python的protobuf SerailizeToString()函数进行序列化。 Here's the code. 这是代码。

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())

Where address_pb2 is the file I generated from the protobuf compiler. 其中address_pb2是我从protobuf编译器生成的文件。 Note that the example is copied from the protoBuf tutorials. 请注意,该示例是从protoBuf教程复制而来的。 This gives me the following string. 这给了我以下字符串。

b'\n\x08John Doe\x10\xd2\t\x1a\x10jdoe@example.com"\x0c\n\x08555-4321\x10\x01'

Now I want to import this string into c++ protobuf. 现在,我想将此字符串导入c ++ protobuf。 For this I wrote the following code. 为此,我编写了以下代码。

#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;
}

Here I am simply trying to import the script using ParseFromString() fucntion but this doesn't work and I am not sure how it will work as I've been stuck on this since a long time now. 在这里,我只是尝试使用ParseFromString()功能导入脚本,但这无法正常工作,我不确定它会如何工作,因为很长一段时间以来我一直坚持这样做。

I tried changing the binary a bit to suit the c++ version but still no idea if I am on the right path or not. 我尝试过更改二进制文件以适合C ++版本,但是仍然不知道我是否在正确的路径上。

How can I achieve this ? 我该如何实现? Does anybody have a clue ? 有人有线索吗?

In Python, you are serializing a Person object. 在Python中,您正在序列化Person对象。 In C++, you are trying to parse an AddressBook object. 在C ++中,您尝试解析AddressBook对象。 You need to use the same type on both ends. 您需要在两端使用相同的类型。

(Note that protobuf does NOT guarantee that it will detect these errors. Sometimes when you parse a message as the wrong type, the parse will appear to succeed, but the content will be garbage.) (请注意,protobuf不能保证会检测到这些错误。有时,当您将消息解析为错误的类型时,解析似乎会成功,但是内容将是垃圾。)


There's another issue with your code that happens not to be a problem in this specific case, but wouldn't work in general: 您的代码还有另一个问题,在这种特定情况下碰巧不是问题,但通常无法正常工作:

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

This line won't work if the string has any NUL bytes, ie '\\x00'. 如果字符串具有任何NUL字节,即'\\ x00',则此行将不起作用。 If so, that byte would be interpreted as the end of the string. 如果是这样,则该字节将被解释为字符串的结尾。 To avoid this problem you need to specify the length of the data, like: 为避免此问题,您需要指定数据长度,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM