flatbuffers 中根类型的目的是什么?

What's the purpose of root type in flatbuffers?

提问人:wibotwi 提问时间:5/3/2023 更新时间:5/3/2023 访问量:355

问:

我的理解是根类型是一些遗留的东西,只需要两个原因:

  1. root_type名称(名称,而不是内容)用于创建某些对象,例如嵌入二进制架构。
  2. 某些语法糖 API 仅针对根类型生成。由于它只是糖,因此您不必使用它。

我是对的还是我错过了什么?

因此,例如,如果我这样做:

table Foo { ... }
table Bar {...}
...

// empty root at the end to make flatbuffers happy
table Fbs {}
root_type Fbs

我给它命名,以便生成的架构看起来不错:. 另一种选择是使用文件名,因为它包含完整文件的二进制架构,因此是有意义的。FbsFbsBinarySchemaMyFileBinarySchema

C++ 平面缓冲区

评论


答:

0赞 Moop 5/3/2023 #1

这对于 flatbuffers 非常重要,而不是遗留的东西。root_type

它用于知道缓冲区引用的表的类型,因此它知道如何解码其内容。

If this is a FlatBuffer binary:

[32-bit offset to root type][... misc ...][root type][... misc ...]
             ^                            ^
             |                            |
This value has the numeric offset to  ----/

目前在架构中,没有 or 表可访问。您需要将它们添加到表中:FooBarFbs

table Fbs {
  my_field:Foo;
  my_other_field:Bar;
  collection_of_foos:[Foo];
}

因此,您应该有一个生成的访问器:

const Fbs* GetFbs(uint8_t * buffer);

这允许您获取根类型/表。从那里,缓冲区中的所有其他内容都可以从根类型引用。

uint8_t* buffer = ... // from somewhere

const Fbs* my_fbs = GetFbs(buffer);

const Foo* my_foo = my_fbs.my_field();

评论

0赞 wibotwi 5/3/2023
看起来你不明白我的问题。“GetFbs” - 这是 GetRoot<T> 的语法糖。GetRoot<T> 接受任何表类型:Foo、Bar。 “目前在您的架构中,无法访问 Foo 或 Bar 表。”这毫无意义。Foo 和 Bar 都可以序列化和反序列化。生成执行此操作的所有方法。序列化 Foo 时,二进制中的root_offset将指向 Foo。当然,该二进制文件将仅包含 Foo。因此,当您反序列化时,您必须知道传入的消息是 Foo。
0赞 Moop 5/3/2023
是的,GetRoot<T> 接受任何类型,但这并不意味着支持二进制文件是该类型。您可以编写而不使用生成的句法糖。但这不是问题,如果您没有根类型(或在您的情况下为空),则没有或任何人都可以访问。GetRoot<Fbs>(buffer)FooBar
0赞 wibotwi 5/3/2023
你说的是什么意思?它们可以通过 和 访问。它有效,我在生产代码中使用它。此外,stackoverflow 上的几个线程说这是访问任何表的正确方法,无论是否 root。no Foo or Bar will be accessible by anyoneGetRoot<Foo>GetRoot<Bar>GetRoot<T>
0赞 Moop 5/3/2023
如果没有 ,则不知道缓冲区中存储了什么。是的,你可以序列化一个 OR,但读者不知道里面有什么。您必须在带外传递该信息:“嘿,我向您发送此缓冲区,它存储偏移量为 0”。它通过在架构本身中对该信息进行编码来为您传达这一点,该架构由编写器/读取器共享。 我的意思是(没有外部信息)读者无法分辨缓冲区中的内容以及如何反序列化它。root_typeFooBarFooroot_typeno Foo or Bar will be accessible by anyone
0赞 wibotwi 5/3/2023
但无论如何,你必须知道你得到了什么。假设我有两个 fbs 文件。它们中的每一个都有根类型。我正在向客户端发送两条消息。客户必须与我沟通“如何解释传入的二进制数据”。我必须告诉他。在 fbs 中保存root_type只是数百万种沟通方式之一。这不是强制性的方式。另一种方法是:将评论存储在 wiki 页面上,甚至是将评论存储在 fbs 文件中。