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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:51:01