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;
关键说明
- 字段号匹配:确保配置的字段号与二进制数据中的wire标签对应。例如数据中的
0a(二进制1010),右移3位后得到字段号2,所以配置时AddField的第一个参数必须为2。 - IsPacked的作用:该属性告诉protobuf-net,这个
repeated字段的数据是用Protobuf3默认的长度前缀格式编码的,而非逐个元素带标签的非打包格式。 - 无装饰要求:整个配置过程无需在类或属性上添加任何ProtoBuf相关的特性装饰,完全通过RuntimeModel的API完成。
配置完成后,protobuf-net就能正确解析0a03010203这类打包格式的repeated int32数据了。
内容的提问来源于stack exchange,提问作者Nomada
相关产品推荐
相关产品推荐

