You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Protobuf.net如何反序列化打包(packed)格式的int数组?

解决Protobuf.net无类装饰时处理repeated int32打包格式的问题

问题核心是Protobuf3默认对repeated int32字段采用**长度前缀(packed)**编码格式,而protobuf-net在无类装饰的默认配置下,不会自动识别这种格式,导致解析时抛出类型不匹配的异常。

解决方案:通过RuntimeModel配置指定字段为Packed格式

在RuntimeModel的字段配置中,显式设置IsPacked = true,告诉protobuf-net该repeated字段的数据采用打包编码。

假设你的ProtobufMessage类定义如下:

public class ProtobufMessage
{
    public object Header { get; set; } // 头部字段,类型根据实际协议调整
    public List<int> Body { get; set; } // 体部为repeated int32
}

对应的RuntimeModel配置代码:

var model = RuntimeModel.Default;
// 注册ProtobufMessage类型,第二个参数设为false表示不自动扫描属性
var typeConfig = model.Add(typeof(ProtobufMessage), false);
// 配置头部字段,假设对应wire标签为1(根据实际协议调整)
typeConfig.AddField(1, nameof(ProtobufMessage.Header));
// 配置体部字段,对应wire标签为2(匹配数据中的0a,即字段号2),并启用Packed
var bodyFieldConfig = typeConfig.AddField(2, nameof(ProtobufMessage.Body));
bodyFieldConfig.IsPacked = true;

关键说明

  1. 字段号匹配:确保配置的字段号与二进制数据中的wire标签对应。例如数据中的0a(二进制1010),右移3位后得到字段号2,所以配置时AddField的第一个参数必须为2。
  2. IsPacked的作用:该属性告诉protobuf-net,这个repeated字段的数据是用Protobuf3默认的长度前缀格式编码的,而非逐个元素带标签的非打包格式。
  3. 无装饰要求:整个配置过程无需在类或属性上添加任何ProtoBuf相关的特性装饰,完全通过RuntimeModel的API完成。

配置完成后,protobuf-net就能正确解析0a03010203这类打包格式的repeated int32数据了。

内容的提问来源于stack exchange,提问作者Nomada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 03:23:12