【发布时间】:2014-11-16 19:09:07
【问题描述】:
我在 C++ protobuf 中重复双字段的序列化时遇到了一个奇怪的问题。 为了练习,我选择了时间序列数据并尝试在我的应用程序中序列化/反序列化。 我在一个 .cpp 文件中重现了错误(参见完整要点),核心思想在这里阅读编写 protobuf 文件,从示例中得到:
void writeMessage(::google::protobuf::Message &message) {
google::protobuf::uint32 size = message.ByteSize();
char buffer[size];
if(!message.SerializeToArray(buffer, size)) {
cerr << "Failed to serialize message: \n" << message.DebugString();
terminate();
}
codedOut->WriteVarint32(size);
codedOut->WriteRaw(buffer, size);
}
bool readMessage(::google::protobuf::Message &message) {
google::protobuf::uint32 size;
if (!codedIn->ReadVarint32(&size)) {
return false;
}
char buffer[size];
if(!codedIn->ReadRaw(buffer, size)) {
cerr << "Can't do ReadRaw of message size " << size << "\n";
terminate();
}
message.ParseFromArray(buffer, size);
return true;
}
对于 1-20 条消息,它可以正常工作,但如果我尝试读取 50 条或更多条消息,那么最后一条消息将被损坏——ReadRaw 将返回 false。如果我尝试忽略 ReadRaw 返回,则消息将包含重复的字段数组,其中包含缺失值和空值。序列化阶段应该没问题,我已经检查了一切。
你能说,我做错了吗?
您可以从这里获得完整的要点: https://gist.github.com/alexeyche/d6af8a43d346edc12868
要重现你只需要做的错误:
protoc -I. --cpp_out=. ./time_series.proto
g++ main.cpp time_series.pb.cc -std=c++11 -L/usr/local/lib -lprotobuf -I/usr/local/include
./a.out synthetic_control_TRAIN out.pb
带有时间序列的 synthetic_control_TRAIN 文件,你可以从这里得到 https://yadi.sk/d/gxZy8JSvcjiVD
我的系统:g++ 4.8.1、ubuntu 12.04、libprotobuf 2.6.1
【问题讨论】:
-
您可以使用
protoc --decode在shell 中解码您的数据。这至少应该说明问题是在编码方面还是在解码方面。
标签: c++ serialization protocol-buffers