FlatBuffers提供的Schemas (又叫IDL, Interface Definition Language) 语法在于c-like, 无论对于C语言用户还是其它IDL用户来说都很容易掌握。
引用官方提供的IDL例子代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| // example IDL file
namespace MyGame;
enum Color : byte { Red = 1, Green, Blue }
union Any { Monster, Weapon, Pickup } // Weapon和Pickup不在该例子中定义
struct Vec3 { x:float; y:float; z:float; }
table Monster { pos:Vec3; mana:short = 150; hp:short = 100; name:string; friendly:bool = false (deprecated, priority: 1); inventory:[ubyte]; color:Color = Blue; test:Any; }
root_type Monster;
|
table && struct
table是Flatbuffers中用来定义对象的主要方式,和struct最大的区别在于:它的每个字段都是可选的(类似protobuf中的optional字段)。而struct的所有成员都是required.
table除了成员名称和类型之外,还可以给成员一个默认值,如果不显式指定,则默认为0(或空)。
struct不能定义scalar成员,比如说string类型的成员。在生成C++代码时,struct的成员顺序会保持和IDL的定义顺序一致,如果有必要对齐,生成器会自动生成用于对齐的额外成员。如以下IDL代码:
1 2 3 4 5 6
| struct STest { a : int; b : int; c : byte; }
|
在生成为C++代码之后,会补充两个用于padding的成员padding0与padding1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| MANUALLY_ALIGNED_STRUCT(4) STest { private: int32_t a_; int32_t b_; int8_t c_; int8_t __padding0; int16_t __padding1;
public: STest(int32_t a, int32_t b, int8_t c) : a_(flatbuffers::EndianScalar(a)), b_(flatbuffers::EndianScalar(b)), c_(flatbuffers::EndianScalar(c)), __padding0(0) {}
int32_t a() const { return flatbuffers::EndianScalar(a_); } int32_t b() const { return flatbuffers::EndianScalar(b_); } int8_t c() const { return flatbuffers::EndianScalar(c_); } }; STRUCT_END(STest, 12);
|
table的成员顺序是动态调整的,这和struct有区别。在生成C++代码时,生成器会自动调整为最佳顺序以保证它占用最小的内存空间。
我们知道用”//“可以在IDL中对文本进行注释以便增加可读性。其实还有一种在生成后的代码中增加注释的方法,就是用”///“。如IDL代码:
1 2 3 4 5 6 7
| /// test structure struct STest { a : int; b : int; c : byte; }
|
生成的C++代码会自动加入注释:
1 2 3 4 5 6
| /// test structure MANUALLY_ALIGNED_STRUCT(4) STest { private: int32_t a_;
// ...
|
Reference : http://google.github.io/flatbuffers/md__schemas.html