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
我担心我想做的事情可能无法实现。
您在第二个代码中缺少
CreateFoo
。
即使这样,将生成的偏移量插入到
buf
中也是行不通的,因为所有 Create
函数都会返回相对于缓冲区末尾的偏移量,而您需要存储的是相对于偏移量本身的偏移量。这在这里不起作用,因为该偏移量将为负数,并且它是一个无符号偏移量。
FlatBuffers 对从父级 -> 子级在缓冲区中向前移动的偏移量有严格要求,因此这是行不通的。
因此,您必须在某个地方找到一块内存来临时存储这些偏移量。