【问题标题】:Is the size prefix for each buffer or entire program?每个缓冲区或整个程序的大小前缀是什么?
【发布时间】:2019-04-11 06:42:11
【问题描述】:

我通过网络流式传输平面缓冲区,因此每个缓冲区都有大小前缀,FinishSizePrefixedFoo(fbb, msg),但我注意到这个大小前缀不是消息结构 msg 的大小,它是整个缓冲区的大小建设者。例如:

flatbuffers::FlatBufferBuilder fbb;
flatbuffers::Offset<Message> msg;
msg = sge::sgedm::CreateMessage(fbb, ...);
FinishSizePrefixedMessageBuffer(fbb, msg);
flatbuffers::uoffset_t len = flatbuffers::ReadScalar<flatbuffers::uoffset_t>(fbb.GetBufferPointer());
std::cout << "Buffer size is " << fbb.GetSize() << " size prefix is " << len << std::endl;
flatbuffers::Offset<Message> msg2;
msg2 = sge::sgedm::CreateMessage(fbb, ...);
FinishSizePrefixedMessageBuffer(fbb, msg2);
len = flatbuffers::ReadScalar<flatbuffers::uoffset_t>(fbb.GetBufferPointer());
std::cout << "Buffer size is " << fbb.GetSize() << " size prefix is " << len << std::endl;

输出是:

Buffer size is 84 size prefix is 80
Buffer size is 168 size prefix is 164

但预期的输出是:

Buffer size is 84 size prefix is 80
Buffer size is 168 size prefix is 80

否则无法将两条消息分开。

我将这个大小前缀用于验证器和反序列化,例如:

buf[4] = recv(4);
uoffset_t len = ReadScalar(buf);
buf[4..len+4] = recv(len);
msg = GetSizePrefixedMessage(buf);

当我读到大小为 164 时,预计会跟随一条大小为 164 的消息,而实际上是两条 80 字节的消息。这是 flatbuffers 的错误吗?

【问题讨论】:

    标签: c++ serialization flatbuffers


    【解决方案1】:

    请确保您使用断言进行开发,因为这已经告诉您上述代码不正确。

    当您在构建器上调用Finish 时,您无法将更多数据序列化到其中,除非您调用Clear。所以在这种情况下,第二个缓冲区也包含第一个缓冲区的副本。断言会告诉你。

    当然,如果您想轻松保持两个缓冲区可用,您也可以使用 2 个FlatBufferBuilder 实例。

    【讨论】:

    • 我启用了#define FLATBUFFERS_ASSERT,没有报告问题。
    • 不,您应该确保在您的平台上以调试模式进行测试。每个平台上的每个 C/C++ 编译器都会在 assert() 调用失败时停止。您出于某种原因没有得到它们。
    • 只是assert没有命中。我在文档中没有找到任何参考,说 Finish 是针对整个构建器的,我认为这意味着完成当前缓冲区。
    • 是的,它们没有被击中,因为您在“发布”模式下编译或其他一些关闭它们的编译器设置。
    • 而构建器拥有一个缓冲区。
    猜你喜欢
    • 2012-08-10
    • 2020-09-05
    • 2019-08-06
    • 2011-04-24
    • 2013-05-19
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多