[英]Protobuf repeated fields deserialization
我在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返回,則消息將包含具有丟失值和null的重復字段數組。 序列化階段應該沒問題,我已經檢查了所有內容。
您能否說,我做錯了嗎?
完整的要點可以從這里獲得: 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
您可以從這里獲取具有時間序列的Composite_control_TRAIN文件https://yadi.sk/d/gxZy8JSvcjiVD
我的系統:g ++ 4.8.1,ubuntu 12.04,libprotobuf 2.6.1
您的數據有多大? 為了安全起見, CodedInputStream
默認為CodedInputStream
的限制,此后它將拒絕讀取更多數據。 您可以使用CodedInputStream::SetTotalBytesLimit()
增加限制,但是更好的解決方案是使用新的CodedInputStream
讀取每個消息。 該類的構造和銷毀速度很快,因此只需將其分配在堆棧上,讀取一條消息,然后使其超出范圍。 (不過,不要重新分配基礎的ZeroCopyInputStream
。)
順便說一句,您似乎正在嘗試仿效Protobuf-Java中存在的parseDelimitedFrom()
格式,而不是Protobuf-C ++中存在的格式,但是您編寫的代碼效率不高:您正在對每個消息進行不必要的復制堆棧。 考慮使用我的StackOverflow答案中的代碼 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.