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

如何从Nanopb Protobuf回调中获取数据而非直接打印?

方案可行性确认与实现示例

这个方案完全可行,通过arg传入字符指针的指针(char**类型),在回调内动态分配内存存储字符串,是替代全局变量的合理做法,具体实现如下:

修改后的回调函数

bool extract_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
{
    // arg指向调用作用域中的char*指针
    char** result_ptr = (char**)*arg;
    size_t str_len = stream->bytes_left;

    // 分配内存,额外+1存储字符串终止符'\0'
    *result_ptr = (char*)malloc(str_len + 1);
    if (*result_ptr == NULL)
        return false;

    // 读取protobuf流中的字符串数据
    if (!pb_read(stream, (uint8_t*)*result_ptr, str_len))
    {
        free(*result_ptr); // 读取失败时释放已分配的内存
        *result_ptr = NULL;
        return false;
    }

    // 添加字符串终止符
    (*result_ptr)[str_len] = '\0';
    return true;
}

调用示例

// 调用作用域中定义存储结果的指针
char* extracted_str = NULL;
// 将指针的地址作为arg传入
void* arg = &extracted_str;

// 配置回调函数
funcs.decode = &extract_string;
funcs.arg = &arg; // 传入arg的地址,符合pb回调的void**参数要求

// 执行protobuf解码操作(比如pb_decode等)
// ...

// 使用完成后记得释放内存,避免泄漏
if (extracted_str != NULL)
{
    printf("提取到的字符串:%s\n", extracted_str);
    free(extracted_str);
    extracted_str = NULL;
}

关键注意事项

  • 必须传入char**类型的地址,因为回调的arg是void**,这样才能在回调内修改调用作用域中指针的指向。
  • 内存分配后若读取失败,要及时释放已分配的内存,避免内存泄漏。
  • 调用作用域在使用完字符串后,必须手动free内存,因为回调内用的是malloc动态分配。

内容的提问来源于stack exchange,提问作者kimfm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:32:04