在 Java 和 C++ 应用程序中使用 protobuf 解析时出错
Posted
技术标签:
【中文标题】在 Java 和 C++ 应用程序中使用 protobuf 解析时出错【英文标题】:Error during parsing with protobuf in Java and C++ Application 【发布时间】:2016-03-22 13:38:45 【问题描述】:我尝试使用 protobuf 在两个 Java 应用程序(客户端和服务器)之间进行消息交换。 protobuf 代码完全用 C++ 开发(也是 TLS 客户端/服务器逻辑)。 “原始” protobuf 类由 C++ 代码包装在一个简单的 C++ 类中,该类只是将方法调用委托给原始 protobuf 代码。这个 C++ 包装器再次使用 SWIG 为 Java 包装。*
我用以下调用填充 java 客户端中的 protobuf:
Message msg = new Message();
msg.setUser("test");
msg.setPassword("pwd");
它将信息委托给 C++ Wrapper 并从那里委托给 protbuf。数据传输正确,但是如果我尝试在java服务器端解析序列化数据,解析失败:
Message message = new Message();
boolean p = message.parse(data); // will call ParseFromString(data); on C++ layer with try catch
但是在服务器应用程序的 c++ 层上它可以正常工作。
我比较了 C++ 和 Java 层(服务器端)上的“原始”protobuf 数据,发现它们看起来不同:
//c++
test�pwd
//java
testÿpwd
长度信息在***上没有显示,但是在java和c++上是一样的。
什么可能导致这种差异?是不是编码有问题?
(*) 我决定采取这额外的步骤,因为在这种情况下,所有 protobuf 逻辑都对 SWIG 隐藏。
注意:我只使用字符串并使用 C++ 中的 parseFromString
和 SerializeAsString
。 Java 不直接调用此方法。
编辑: 消息还有两个字段“布尔成功”和“字符串名称”。如果我同时删除它们,则解析工作(用户和密码之间的符号消失了)。为什么?
message Message
required string user = 1;
optional string pwd = 2;
//optional string name = 3;
//optional bool success = 4;
编辑 这确实是 Java 字符串编码的问题。另请参阅我的其他相关问题here on ***
【问题讨论】:
“原始”数据的实际字节数是多少?你能展示你的java服务器解析代码吗? 实际字节如上所示,它们在一个位置不同。我将从 java 服务器端添加代码。 它们有何不同,实际的字节值是多少(作为数字)? 在我看来可能是一个愚蠢的问题,但是:我如何才能看到“字节值”? 将每个“char”视为一个 int。int i = 0xFF & c
【参考方案1】:
查看 protobuf java api,它总是使用“byte[]”作为序列化数据。我怀疑您遇到了问题,因为 java 字符串与 c++ 字符串不同。我会专门将 byte[] 用于 Java 中的数据。
【讨论】:
以上是关于在 Java 和 C++ 应用程序中使用 protobuf 解析时出错的主要内容,如果未能解决你的问题,请参考以下文章
在 Java 和 C++ 应用程序中使用 protobuf 解析时出错
C++学习(四五一)public protected private权限和继承方式