序列化表向量而不创建临时偏移向量

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

使用

flatbuffers
v2.0.8
,我尝试序列化表向量而不创建临时的
std::vector
偏移量。

这在以下情况下特别有用:

  • 尝试将一个平面缓冲区重新序列化为另一个平面缓冲区。
  • 开发嵌入式/实时软件,我无法随时分配内存。
    • (在这个用例中,
      flatbuffers::FlatBufferBuilder
      是我需要的唯一内存分配,并且是在方便的地点和时间完成的)。

我尝试使用

CreateUninitializedVector()
在构建器内为所述向量分配空间,并稍后填充它,但它不起作用:平面缓冲区似乎没有正确序列化。

这是我的代码:

  • protocol.fbs
    flatc --scoped-enums --cpp --cpp-std c++17 --gen-object-api
    编译。
namespace protocol;

table Foo {
    id: string;
}

table Message {
    foos: [Foo];
}
  • main.cpp
#include <flatbuffers/flatbuffers.h>
#include <iostream>
#include "protocol_generated.h"

void deserialize(flatbuffers::FlatBufferBuilder& builder) {
    if (auto verifier = flatbuffers::Verifier(builder.GetBufferPointer(), builder.GetSize());
            verifier.VerifyBuffer<protocol::Message>())
        std::cout << "protocol::Message looks correctly serialized\n";
    else
        std::cout << "Couldn't verify buffer to be of type protocol::Message\n";
}

int main() {
    std::vector<std::string_view> ids = {"toto", "titi", "tata", "tutu"};
    {
        // This works, but needs a temporary std::vector
        flatbuffers::FlatBufferBuilder builder;
        std::vector<flatbuffers::Offset<protocol::Foo>> vec;

        for (auto const id: ids)
            vec.push_back(protocol::CreateFoo(builder, builder.CreateString(id)));
        auto const offset = protocol::CreateMessage(
                builder,
                builder.CreateVector(vec)
        );
        builder.Finish(offset);

        deserialize(builder);
    }
    {
        // This is NOT OK
        flatbuffers::FlatBufferBuilder builder;
        flatbuffers::Offset<flatbuffers::String>* buf = nullptr;
        auto const offset = protocol::CreateMessage(
                builder,
                builder.CreateUninitializedVector(ids.size(), sizeof(flatbuffers::Offset<flatbuffers::String>), reinterpret_cast<uint8_t **>(&buf))
        );
        for (size_t i = 0; i < ids.size(); ++i)
            buf[i] = builder.CreateString(ids[i]);
        builder.Finish(offset);

        deserialize(builder);
    }
    return 0;
}

我得到以下输出:

protocol::Message looks correctly serialized
Couldn't verify buffer to be of type protocol::Message

我担心我想做的事情可能无法实现。

c++ serialization flatbuffers
1个回答
0
投票

您在第二个代码中缺少

CreateFoo

即使这样,将生成的偏移量插入到

buf
中也是行不通的,因为所有
Create
函数都会返回相对于缓冲区末尾的偏移量,而您需要存储的是相对于偏移量本身的偏移量。这在这里不起作用,因为该偏移量将为负数,并且它是一个无符号偏移量。

FlatBuffers 对从父级 -> 子级在缓冲区中向前移动的偏移量有严格要求,因此这是行不通的。

因此,您必须在某个地方找到一块内存来临时存储这些偏移量。

© www.soinside.com 2019 - 2024. All rights reserved.