使用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; }
关键修改点
- 提前获取字符串长度并检查缓冲区容量,避免内存溢出
- 在有效字节末尾手动添加
\0,截断后续垃圾数据 - 保留原有解码逻辑,确保流程正常执行
内容的提问来源于stack exchange,提问作者J.Meulenbeld
相关产品推荐
相关产品推荐

