我的 Protobuf 消息由 3 个 double 组成
syntax = "proto3";
message TestMessage{
double input = 1;
double output = 2;
double info = 3;
}
当我将这些值设置为
test.set_input(2.3456);
test.set_output(5.4321);
test.set_info(5.0);
序列化的消息看起来像
00000000 09 16 fb cb ee c9 c3 02 40 11 0a 68 22 6c 78 ba |........@..h"lx.|
00000010 15 40 19 |.@.|
00000013
当使用 test.serializeToArray
并且无法通过使用相同 protobuf 消息的 go 程序成功反序列化时。当试图从 C++ 程序中读取它时,我得到了一个 0 作为信息,因此消息似乎已损坏。
当使用 test.serializeToOstream
时,我得到了这个消息,go 和 c++ 程序都可以成功反序列化它。
00000000 09 16 fb cb ee c9 c3 02 40 11 0a 68 22 6c 78 ba |........@..h"lx.|
00000010 15 40 19 00 00 00 00 00 00 14 40 |.@........@|
0000001b
将值设置为
test.set_input(2.3456);
test.set_output(5.4321);
test.set_info(5.5678);
test.serializeToArray
和 test.serializeToOstream
生成的序列化消息看起来像
00000000 09 16 fb cb ee c9 c3 02 40 11 0a 68 22 6c 78 ba |........@..h"lx.|
00000010 15 40 19 da ac fa 5c 6d 45 16 40 |.@....\mE.@|
0000001b
并且可以被我的 go 和 cpp 程序成功读取。
我在这里错过了什么?为什么 serializeToArray
在第一种情况下不起作用?
编辑: 事实证明,serializeToString 也能正常工作。
这里是我用来比较的代码:
file_a.open(FILEPATH_A);
file_b.open(FILEPATH_B);
test.set_input(2.3456);
test.set_output(5.4321);
test.set_info(5.0);
//serializeToArray
int size = test.ByteSize();
char *buffer = (char*) malloc(size);
test.SerializeToArray(buffer, size);
file_a << buffer;
//serializeToString
std::string buf;
test.SerializeToString(&buf);
file_b << buf;
file_a.close();
file_b.close();
为什么 serializeToArray 没有按预期工作?
编辑2:
当使用 file_b << buf.data()
而不是 file_b << buf.data()
时,数据也会损坏,但为什么呢?
最佳答案
我认为您犯的错误是将二进制视为字符数据并使用字符数据 API。许多 API 在第一个零字节 (0) 处停止,但这是 protobuf 二进制文件中完全有效的值。
您需要确保基本上不使用任何此类 API - 纯粹使用二进制安全 API。
因为您指出 size
是 27,所以这一切都合适。
基本上,5.0 的二进制表示包括 0 个字节,但您很容易及时发现其他值的相同问题。
关于c++ - 当对字段使用不同的值时,Protobuf 序列化长度不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44806362/