Protobuf 解析预分配的数据并无需复制即可输出

问题描述 投票:0回答:1

我正在研究在我的嵌入式物联网框架中采用 Protobuf,其中可以从 MQTT/HTTP/等网络源接收消息并将其馈送到系统。

我寻求完全处理传入的数据而不复制它,因此预期用途是将起始地址

std::uint8_t*
和大小提供给protobuf。

消息的基本模式是:

message Message {
    optional string str = 1;
    optinal bytes raw = 2;
}

数组数据(字符串和原始数据)的预期输出分别是

std::string_view
std::span
*,它们将指向接收到的数据。

那么为了避免不必要的副本,这是否适用?如果是这样,怎么办?

* 任何一对

std::uint8_t*
size_t
指向相关数据都是可接受的。

c++ protocol-buffers c++20
1个回答
0
投票

我不知道如何使用现有的消息结构通过 Google 的 C++ protobuf 库来实现此目的。可以使用较低级别的函数逐个字段进行解析,但是这样您就无法享受从原始文件自动生成的代码的好处。

看起来应该可以使用 nanopb,尽管我还没有具体尝试过。默认情况下,nanopb 将为字符串生成回调或静态数组,但这可以用生成器选项覆盖。

对于您的示例,

myproto.options
文件将包含:

*         include:"span"
msg.raw   callback_datatype:"std::span<uint8_t>", callback_function="bytes_to_span"

并且您将提供用于转换的命名回调函数:

bool bytes_to_span(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
{
    if (istream)
    {
        // Copy pointer to field contents in input stream into a std::span in message structure.
        auto result = static_cast<std::span<uint8_t>*>(field->pData);
        *result = std::span<uint8_t>(istream->state, istream->bytes_left);
    }

    return true;
}
© www.soinside.com 2019 - 2024. All rights reserved.