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

使用NanoPB解码字符串字段时末尾出现冗余字符的问题求助

解决NanoPB字符串解码末尾冗余字符问题

问题场景

使用NanoPB解码Proto字符串字段时,内容主体正确,但末尾始终出现乱码冗余字符。相关代码及现象如下:

Proto消息定义

syntax = "proto2";

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

自定义解码函数

bool stringCallback_decode(pb_istream_t *stream, const pb_field_t *field, void** arg)
{
  //Buffer to store the decoded string
  char buffer[128];
  //Check how many bytes the string will be
  Serial.println(stream->bytes_left);

  //Decode the string and store it in the buffer
  if (!pb_read(stream, (uint8_t*)buffer, stream->bytes_left))
      return false;
  
  //Copy the string into the arg to place it in its placeholder
  strcpy((char*)*arg, buffer);
  
  //Print the string (gibberish)
  Serial.println((char*)*arg);
  return true;
}

测试现象

输入消息为␆Doesnt␒␄Work␘␗(对应name="Doesnt"、surname="Work"、age=23),解码后输出:

bytes left = 6 -> output: Doesnt�?P&�? 
bytes left = 4 -> output: Worknt�?P&�?

问题原因

C语言字符串依赖**\0(空字符)**标识结束位置,但NanoPB的pb_read()仅读取字符串的有效字节,不会自动添加结束符。此时buffer中读取的内容后是内存中的随机垃圾数据,strcpy和Serial.println会持续读取直到遇到内存中的第一个\0,导致末尾出现乱码。

修复方案

在pb_read()读取完成后,手动在有效字节末尾添加\0,同时提前检查缓冲区容量避免越界:

修改后的解码函数:

bool stringCallback_decode(pb_istream_t *stream, const pb_field_t *field, void** arg)
{
  char buffer[128];
  size_t str_len = stream->bytes_left;
  
  // 确保缓冲区有足够空间存放字符串+结束符
  if (str_len >= sizeof(buffer))
      return false;
  
  Serial.println(str_len);

  if (!pb_read(stream, (uint8_t*)buffer, str_len))
      return false;
  
  // 添加字符串结束符,明确结束位置
  buffer[str_len] = '\0';
  
  // 复制到目标地址
  strcpy((char*)*arg, buffer);
  
  Serial.println((char*)*arg);
  return true;
}

关键修改点

  1. 提前获取字符串长度并检查缓冲区容量,避免内存溢出
  2. 在有效字节末尾手动添加\0,截断后续垃圾数据
  3. 保留原有解码逻辑,确保流程正常执行

内容的提问来源于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 15:15:33