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

NanoPB编码重复int32值后C#解码数值翻倍问题排查

问题:Protobuf编码int数组经MQTT发送后,C#端解码数值翻倍

将int数组编码为Protobuf消息后通过MQTT发送至C#应用,解码时出现异常:C#端得到的所有int32数值均翻倍,但把相同字节数据回传给NanoPB应用解码时,数值显示正常。

相关文件及输出

Proto定义文件

syntax = "proto2";

message stringCallback{
    required string name = 1;
    required string surname = 2;
    required int32 age = 3;
    repeated int32 values = 4;
}

NanoPB编码函数

bool IntArray_encode(pb_ostream_t *ostream, const pb_field_t *field, void* const* arg){
  IntArray* arr = (IntArray*)*arg;
  
  for(int i = 0; i < arr->count; i++){
    if(!pb_encode_tag_for_field(ostream, field)){
      Serial.println("Encoding failed!");
      return false;
    }

    if(!pb_encode_svarint(ostream, arr->values[i])){
      Serial.println("Encoding failed!");
      return false;
    }
  }

  return true;
}

NanoPB解码函数

bool IntArray_decode(pb_istream_t *stream, const pb_field_t *field, void** arg){
  IntArray* arr = (IntArray*)*arg;
  int64_t number;

  if(!pb_decode_svarint(stream, &number)){
    Serial.println("Decoding failed!");
    return false;
  }

  Serial.println(number);
  IntArray_add(arr, (int32_t)number);

  return true;
}

NanoPB解码输出

Name = Testing
Surname = Purpose
Age = 23
[14 11 10 5 109 32321 23 19 15]

C#解码输出

Name = Testing
Surname = Purpose
Age = 23
[28 22 20 10 218 64642 46 38 30 ]

问题原因

Proto文件中values字段定义为标准int32类型,但NanoPB编码时使用了pb_encode_svarint函数——该函数是针对sint32/sint64类型设计的,会对数值执行ZigZag编码。而C#端的Protobuf库会按照标准int32的规则解码(不处理ZigZag),正数的ZigZag编码结果恰好是原数值的2倍,因此出现了数值翻倍的异常。

解决方案

有两种修复方式:

  1. 修改编码逻辑:将NanoPB编码中的pb_encode_svarint替换为pb_encode_varint,标准int32在Protobuf中使用varint编码(无ZigZag):
    if(!pb_encode_varint(ostream, arr->values[i])){
      Serial.println("Encoding failed!");
      return false;
    }
    
  2. 统一字段类型:将Proto文件中的values字段类型改为sint32,这样两端都会采用ZigZag编解码规则,结果即可统一:
    repeated sint32 values = 4;
    

内容的提问来源于stack exchange,提问作者J.Meulenbeld

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 18:48:24