Protobuf Packed字段打包uint16_t到uint32_t后反序列化值不匹配问题
问题分析与解决
你的问题和Protobuf的特殊机制无关,核心是序列化代码的语法错误,导致实际打包的数据根本不是你预期的两个uint16_t的组合值。
错误点解析
看你的序列化代码:
uint16_t value1 = 100; // Arbitrary values uint16_t value2 = 200; protoObject.add_fingerprints((uint32_t)value1 << 16) + value2;
这里的加法运算符+作用在add_fingerprints()的返回值上,而不是作用在(uint32_t)value1 << 16和value2上。也就是说,你实际只把(uint32_t)value1 <<16这个值添加到了fingerprints列表里,value2完全没参与打包,反序列化自然得不到正确结果。
修正后的序列化代码
需要把合并操作放到函数参数内部,确保是两个值合并后再传入:
uint16_t value1 = 100; // Arbitrary values uint16_t value2 = 200; protoObject.add_fingerprints( ((uint32_t)value1 << 16) | value2 );
用位或|和加法+效果一致(两个uint16_t的位域无重叠),但位或更能体现“打包两个独立位段”的语义。
反序列化代码验证
你的反序列化逻辑是正确的:
uint16_t value1 = protoObject->fingerprints(i) >> 16; uint16_t value2 = protoObject->fingerprints(i) & 0x0000FFFF;
修正序列化代码后,反序列化就能得到和原始一致的value1和value2。
补充说明
Protobuf的packed=true只是对重复字段的序列化方式做优化(用连续字节流存储,而非每个元素带字段标签),不会修改字段本身的数值,和你的问题无关。
内容的提问来源于stack exchange,提问作者Baiqing
相关产品推荐
相关产品推荐

