如何从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
相关产品推荐
相关产品推荐

