[英]Cannot deserialize protobuf data from C++ in Java
我的問題是用C ++序列化protobuf數據並用Java反序列化數據。 這是我用於dcn給出的提示的代碼:
有了這個,我用C ++創建protobuf數據並將其寫入通過套接字發送的ostream。
Name name;
name.set_name("platzhirsch");
boost::asio::streambuf b;
std::ostream os(&b);
ZeroCopyOutputStream *raw_output = new OstreamOutputStream(&os);
CodedOutputStream *coded_output = new CodedOutputStream(raw_output);
coded_output->WriteLittleEndian32(name.ByteSize());
name.SerializeToCodedStream(coded_output);
socket.send(b);
這是我嘗試解析它的Java端:
NameProtos.Name name = NameProtos.Name.parseDelimitedFrom(socket.getInputStream());
System.out.println(name.newBuilder().build().toString());
但是,我得到了這個例外: com.google.protobuf.UninitializedMessageException:消息缺少必填字段:name
我錯過了什么?
有缺陷的代碼行是: name.newBuilder().build().toString()
這將永遠不會起作用,使用未初始化的名稱字段創建新實例。 無論如何,這里的答案解決了我的其余問題。
最后一件事,我在protobuf郵件列表中被告知:為了刷新CodedOutputStreams,必須刪除對象!
delete coded_output;
delete raw_output;
我不知道你的Java代碼received
什么,但你的問題可能是由於一些字符集轉換。 另請注意,protobuf在序列化時不會分隔消息。
因此,您應該使用原始數據來傳輸消息(字節數組或直接(de)從/向流序列化)。 如果您打算發送許多消息,您還應該在發送實際消息之前發送大小。
在Java中,您可以通過parseDelimitedFrom(InputStream)
和writeDelimitedTo(OutputStream)
直接執行此操作。 使用CodedOutputStream
就可以在C ++中執行相同的操作
codedOutput.WriteVarint32(protoMessage.ByteSize());
protoMessage.SerializeToCodedStream(&codedOutput);
另見這個更早的線程。
您正在向流寫入兩個內容,一個大小和Name
對象,但只是嘗試讀取一個。
作為一般問題:為什么你覺得需要使用CodedInputStream? 引用文檔 :
通常,這些類僅由協議緩沖庫在內部使用,以便對協議緩沖區進行編碼和解碼。 如果他們希望編寫自定義消息解析或序列化過程,則庫的客戶端只需要知道該類
並強調jtahlborn的評論:為什么小端? Java處理大端值,因此必須在讀取時進行轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.