在 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++ 中的 parseFromStringSerializeAsString。 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 解析时出错

编程——JAVA与JOK与IDE基础篇

如何在 Protégé 中创建财产?

C++学习(四五一)public protected private权限和继承方式

是否可以在 C++ 继承中“取消私有”元素?如果没有怎么办?

C++ 和 Java 对象通信