Nanopb 从 pb_ostream_t 获取字符串

Posted

技术标签:

【中文标题】Nanopb 从 pb_ostream_t 获取字符串【英文标题】:Nanopb get string from pb_ostream_t 【发布时间】:2015-07-07 15:19:05 【问题描述】:

我正在使用nanopb,因此我可以使用一些小的交叉编译代码来实现 protobuf。我有它工作的基础,但希望将编码的 protobuf 消息作为字符串通过 UDP(在另一个系统上)发送。通常使用完整的 protobuf 库,您可以执行message.serializeToString() 之类的操作。 Nanopb 似乎没有,但肯定是很常见的事情。 nanopb 给出的示例使用了他们的 pb_ostream_t 结构和pb_ostream_from_buffer() 有什么想法吗?

【问题讨论】:

【参考方案1】:

在 C 中,二进制字符串只是一个 uint8_t 数组。 (请注意,普通的 C 字符串不能包含二进制数据,因此不能用于存储 protobuf 消息。)

所以 pb_ostream_from_buffer() 是获取“字符串”结果的正确方法。

取自simple.c example:

uint8_t buffer[128];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
status = pb_encode(&stream, SimpleMessage_fields, &message);

之后编码的消息位于buffer 中,长度为stream.bytes_written。那就是你想要的字符串。

【讨论】:

我没有听懂你所说的“普通 C 字符串不能包含二进制数据”。这不是标准 protobuf serializeToString() 在做什么吗?基本上我想将“字符串”导出回另一个系统,然后通过 UDP 发送它。 @ChuckClaunch 如果您指的是 C++ protobuf 库中的 serializeToString(),它会序列化为 C++ 字符串,该字符串确实可以包含二进制数据。 C 字符串以空值结尾,并且不能包含空字节,因此它不能包含二进制数据。 Nanopb 是一个 C 库,因此它不会直接序列化为 C++ 字符串(尽管编写自己的包装器相对简单)。 啊,是的,现在说得通了。我最终通过将 uint8_t 数组传回并让用户代码处理发送来解决我的问题。感谢您的回答! @jpa 我有什么标准方法可以将编码消息作为字符串发送吗?我最终转换为包含十六进制数字的字符串,但缓冲区的大小是双倍的。 @MasoudR。阅读您的另一个问题,您的主要问题似乎是二进制数据中的 0 字节。试图通过任何编码(例如 base64、cob)来避免它们总是会增加数据的大小。

以上是关于Nanopb 从 pb_ostream_t 获取字符串的主要内容,如果未能解决你的问题,请参考以下文章

无法构建模块“nanopb”

nanopb的使用

Nanopb - 解码失败:零标签

无法在 Xcode 12.0.1 中构建模块“nanopb”错误

nanopb oneof 尺寸要求

我需要用 Protobuf 存储长度信息吗?