如何在Nanopb中逐项解码重复消息
逐行解码Nanopb中的Repeated Row消息
给定以下Nanopb消息定义:
syntax = "proto3"; message Row { uint32 startAddress = 1; bytes data = 2; } message File { repeated Row row = 1; }
需要解码包含多个Row的File消息,但要求逐行处理,避免在内存中同时存储所有行的编码态和解码态。你提供的伪代码直接循环解码Row的方式无法正确处理File消息的结构,需通过Nanopb的回调机制实现需求。
正确实现方案
Nanopb支持为repeated字段设置回调函数,解析到单个Row时自动触发回调,从而实现逐行处理,无需缓存所有行。具体实现如下:
完整代码示例
#include <nanopb/pb_decode.h> #include "your_proto_file.pb.h" // 替换为实际生成的proto头文件 // 单个Row的处理回调函数,返回true继续解析,false终止解码 bool process_row(pb_istream_t *stream, const pb_field_t *field, void **arg) { Row row = Row_init_zero; // 初始化Row结构体 // 解析当前Row消息 if (!pb_decode(stream, Row_fields, &row)) { return false; } // 执行业务处理逻辑 DoingStuffWithRow(row); // 释放Nanopb为bytes字段分配的内存,避免泄漏 if (row.data.data != NULL) { pb_release(Row_fields, &row); } return true; } void decode_File(const std::uint8_t* data, std::size_t length) { File file_msg = File_init_zero; pb_istream_t istream = pb_istream_from_buffer(data, length); // 为repeated的row字段绑定回调,替代默认的数组存储行为 file_msg.row.funcs.decode = &process_row; // 解码整个File消息,过程中自动调用回调处理每个Row if (!pb_decode(&istream, File_fields, &file_msg)) { // 处理解码错误,例如打印pb_get_error(&istream) } }
关键细节说明
Row_init_zero是Nanopb生成的初始化宏,用于将结构体置为默认值- 回调函数中处理完当前
Row后,需调用pb_release释放bytes类型字段的动态内存 - 回调返回
true会继续解析下一个Row,返回false则终止整个解码流程 - 解码过程中内存仅保留当前正在处理的
Row实例,不会缓存所有行
内容的提问来源于stack exchange,提问作者peter
相关产品推荐
相关产品推荐

