无法从Java中的C ++反序列化protobuf数据

问题描述

| 我的问题是在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.newBuilder().build().toString()
这将永远无法实现,将使用未初始化的名称字段创建一个新实例。无论如何,这里的答案解决了我其余的问题。 在protobuf邮件列表中告诉我的最后一件事:为了刷新CodedOutputStreams,必须删除对象!
delete coded_output;
delete raw_output;
    

解决方法

我不知道Java代码中的“ 4”是什么,但是您的问题可能是由于字符集转换引起的。还要注意,protobuf在序列化时不会分隔消息。 因此,您应该使用原始数据来传输消息(字节数组或直接从/到流(反)序列化)。 如果您打算发送许多邮件,则在发送实际邮件之前,还应该发送大小。 在Java中,您可以直接通过
parseDelimitedFrom(InputStream)
writeDelimitedTo(OutputStream)
进行操作。您可以使用
CodedOutputStream
在C ++中完成相同的操作,但复杂得多,例如
codedOutput.WriteVarint32(protoMessage.ByteSize());
protoMessage.SerializeToCodedStream(&codedOutput);
另请参见该线程。     ,您正在向流中写入两件事,一个大小和一个“ 9”对象,但仅尝试读取其中一个。 作为一个普遍的问题:为什么您觉得需要使用CodedInputStream?引用文档:   通常,这些类将仅   由协议缓冲区内部使用   库以进行编码和解码   协议缓冲区。客户   图书馆只需要知道这一点   如果他们想写习俗的话   消息解析或序列化   程序 并强调jtahlborn的评论:为什么选择低端字节序? Java处理big-endian值,因此必须在读取时进行转换。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...