【问题标题】:C# protobuf-net serialized object to javaC# protobuf-net 序列化对象到 java
【发布时间】:2023-03-08 19:42:01
【问题描述】:

所以我有一个小问题:

使用 MQTT 发送消息,它由一系列使用 C# 中的 protobuf-net 序列化的对象组成(我无法修改此代码,但我可以访问源代码)。在另一端,我收到了 Java 中的序列化对象,问题是我似乎无法使用 protobuf 反序列化对象,如果有人遇到过这个问题并解决了它,请帮助:)

来自 C# 的对象示例:

using ProtoBuf;

namespace Concentrator.Services
{
[ProtoContract]
public class MeterID
{
    private byte[] _id;

    [ProtoMember(1)]
    public byte[] ID
    {
        get { return _id; }
        set { _id = value.Length == 16 ? value : null; }
    }

    [ProtoMember(2)] public string MeterType;
}
}

我尝试在 Java 中重新创建相同的对象(.proto 文件):

syntax = "proto2";

 package mqtt.entity;

 option java_package = "mqtt.entity";
 option java_outer_classname = "ProtoMeter";
 message Meter {
    optional bytes ID = 1;
     optional string MeterType = 2;
  }

  message MeterID {
     repeated Meter mid = 1;
 }

这个例子的解决方案将是一个巨大的帮助,非常感谢。

C#中反序列化对象的代码:

var ms = new MemoryStream(data, 7, data.Length - 9)
var res = Serializer.Deserialize<List<MeterID>>(ms);

这在 C# 中有效,我正在尝试在 java 中实现相同的目标

【问题讨论】:

  • 您说“我似乎无法反序列化对象”,但是当您尝试时会发生什么?编译错误?运行时错误?数据损坏?
  • 尝试反序列化时验证错误

标签: c# java serialization protocol-buffers protobuf-net


【解决方案1】:

您的 C# 代码中的消息仅匹配:

message MeterID {
    optional bytes ID = 1;
    optional string MeterType = 2;
}

不需要 2 级模型(除非您在 C# 代码中使用 *WithLengthPrefix)。您还可以使用以下命令获取该输出:

var proto = Serializer.GetProto<MeterID>();

通过您的编辑,List&lt;MeterID&gt; 可以映射为

message List_MeterID {
    repeated MeterID items = 1;
}

与之前的MeterID 片段结合使用。这就是你的问题。所以归结为“目前发生了什么?”。

【讨论】:

  • 我正在尝试在 java 中反序列化,对象出现在列表中,我将更新第一篇文章以添加在 C# 中反序列化的代码
  • @cdanisor 您没有提到List&lt;T&gt; :p 这样,您原始问题中的 .proto 就可以了。那么这就提出了一个问题——现在会发生什么?什么不起作用?你有例外吗...?还是...?
  • 现在还有一个问题 :) 线程“MQTT 客户端回调”java.lang.VerifyError 中的异常:类 mqtt.entity.ProtoMeter$MeterID 覆盖最终方法 getUnknownFields.()Lcom/google/protobuf/未知字段集;在 java.lang.ClassLoader.defineClass1(Native Method) protoc 生成的类似乎有问题,它覆盖了一个 final 方法。
  • @cdanisor 首先检查您是否拥有 google protobuf(不是 protobuf-net)包的当前版本;如果protoc 仍然发出非法java,那么我建议在protobuf list 或protobuf(不是protobuf-net)issue tracker 上报告它
  • 你是对的,我使用了错误版本的 protoc,与 jar 不同,它现在可以完美运行。非常感谢。
【解决方案2】:

尝试通过GetProto&lt;T&gt;重新生成原始文件

【讨论】:

  • 请说得更具体一些,我以前从未使用过 protobuf
  • var res = Serializer.GetProto&lt;List&lt;MeterID&gt;&gt;; 并使用res
  • 好的,在 C# 中得到它是一个很好的步骤,但我如何在 java 中导出它?
  • @cdanisor 与大多数代码相比,GetProto&lt;T&gt; 的重新实现相对较新 - 我认为它可以处理大多数情况,但如果您遇到任何问题,请告诉我
猜你喜欢
  • 2011-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
相关资源
最近更新 更多