Protobuf Java 到 C++ 序列化 [二进制]

Protobuf Java To C++ Serialization [Binary]

我有一个程序在 Java 中使用 Protobuf 序列化数据,方法是将二进制数据写入 byte[] 数组,然后将其保存在“.txt”文件中。我在字符串流中的 C++ 端接收到该数据。现在我想用 C++ 解析二进制数据,但是 Protobuf-Parsing-Method "parseFromString()" 不起作用!我的测试消息中的字段未设置。我为此写了一个小测试,我可以给你看一些代码:

Java连载

  byte[] s = test.build().toByteArray(); //This is serialized to "C:\test.txt" as binary

C++ 解析:

Test t1; // My Protobuf Message
std::ifstream myFile("C:\test.txt");
std::string s;
myFile >> s;

t1.ParseFromString(s);
std::cout << "Decoded: " << t2.s() << std::endl; // Check if parsing was correct

但它只是 returns: " Decoded: ",好像 t2 是空的,但它不应该是!如何在 C++ 中解析二进制数据?

问题是您在混合调用 API。您正在使用 toByteArray API 调用进行序列化,并使用 ParseFromString API 调用进行反序列化。

您可以使用其中一对,但不能混用:

  • ParseFromStringSerializeToString
  • SerializeToArrayParseFromArray

我正在编写 C++ 和 python。我附上了我的代码中的以下示例。我想你应该能够从这个例子中理解它是如何工作的。 如果有什么不明确的地方请给我留言。

这是我的 python 连载:

socket.send(request.SerializeToString())

和C++反序列化:

// Deserialize request.
if (request.ParseFromString(protobuf_request) == false) {
    throw exception();
}

这是我的 C++ 序列化:

// Serialize response.
assert(response.SerializeToString(&protobuf_response) == true);

和python反序列化:

response.ParseFromString(str(message))

编辑:

我认为你应该使用:

  • void writeTo(OutputStream 输出);在 Java
  • bool ParseFromIstream(istream* 输入);在 C++

你的问题可能出在这里:

myFile >> s;

>> 运算符读取 text 字符串,由空格分隔。编码的 protobuf 不是文本。可能 ParseFromString() 返回 false 表示它无法解析数据,因为它不完整。

您要做的是读取整个文件。在您的情况下执行此操作的最简单方法是使用 ParseFromIstream(&myFile)。 (并确保检查它 returns 是真的!)

(另一种选择是检查文件大小,创建该大小的数组,使用 myFile.read(array, size),然后使用 ParseFromArray(array, size),但这需要做更多的工作来做同样的事情.)

请注意,您可能不应该使用 .txt 作为 protobuf 的文件扩展名,因为该文件不包含文本。

另请注意,令人困惑的是,在 C++ 中,您可以将二进制(非文本)数据放入 std::string -- 它只是一个字节容器 -- 但在 Java 中,您 不能将二进制数据放在String中。所以 C++ ParseFromString()SerializeAsString() 处理二进制数据,而 Java toString() 实际上 returns 消息的文本表示(用于调试目的) 不是您要传输的内容。