与ProtoBuf类似,这是一种序列化工具,把编程语言的数据结构转成二进制内容,保存到文件中(ProtoBuf网络传输),以及方便地从文件中再次恢复。
Write your own schema(.fbs)
// Example IDL file for our monster's schema.
namespace MyGame.Sample;
enum Color:byte { Red = 0, Green, Blue = 2 }
union Equipment { Weapon } // Optionally add more tables.
struct Vec3 {
x:float;
y:float;
z:float;
}
table Monster {
pos:Vec3;
mana:short = 150;
hp:short = 100;
name:string;
friendly:bool = false (deprecated);
inventory:[ubyte];
color:Color = Blue;
weapons:[Weapon];
equipped:Equipment;
path:[Vec3];
}
table Weapon {
name:string;
damage:short;
}
root_type Monster;
- enum, union, struct这些都会与C语言概念一一对应
- table有所不同(struct 有稳定的结构,数据inline保存) 通过生成的c代码可以看到,table结构体几乎没有成员变量,不占用空间,数据通过偏移保存。
- root_type 标识主结构体
注意:当一个个object填入Binary的顺序是逆序的,也就是最先创建的Object位于Binary的最后面,Object里面具体的内容是顺序填充的。
Generate C header from above schema
运行以下命令会自动生成monster_generated.h文件
flatc --cpp C:\Users\glu\Desktop\flatbuffers\samples\monster.fbs
Write to flatBuffer
create a vector of nested objects
例如:tables, strings, vectors 这都都是间接存储的,vector里面存的是偏移值。
不能直接使用string,vector等去构建某个对象,需要通过offset对象去构建,因此先通过create函数去创建offset对象。
Offset<String> CreateString(const char *str)
Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v)
- 创建各自的offset
- offset存入std::vector 示例代码如下
// Place the weapons into a `std::vector`, then convert that into a FlatBuffer `vector`.
std::vector<flatbuffers::Offset<Weapon>> weapons_vector;
weapons_vector.push_back(sword);
weapons_vector.push_back(axe);
auto weapons = builder.CreateVector(weapons_vector);
create a vector of common objects
例如:struct, 标量等,这些都是直接存储的(inline)
如果tables等也以这种方式存储,程序会报错。
Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
auto path = builder.CreateVectorOfStructs(points, 2);
the other optional way(convenient )
// You can use this code instead of `CreateMonster()`, to create our orc
// manually.
MonsterBuilder monster_builder(builder);
monster_builder.add_pos(&position);
monster_builder.add_hp(hp);
monster_builder.add_name(name);
monster_builder.add_inventory(inventory);
monster_builder.add_color(Color_Red);
monster_builder.add_weapons(weapons);
monster_builder.add_equipped_type(Equipment_Weapon);
monster_builder.add_equipped(axe.Union());
auto orc = monster_builder.Finish();
get the buffer
uint8_t *buf = builder.GetBufferPointer();
int size = builder.GetSize(); // Returns the size of the buffer that
// `GetBufferPointer()` points to.
Read from flatBuffer
Mutating flatBuffer
支持局部修改flatBuffer,避免了再次生成整个Buffer.
auto monster = GetMutableMonster(buffer_pointer); // non-const
monster->mutate_hp(10); // Set the table `hp` field.
monster->mutable_pos()->mutate_z(4); // Set struct field.
monster->mutable_inventory()->Mutate(0, 1); // Set vector element.
JSON
.fbs 文件描述了二进制文件的结构/格式,通过代码进行添加具体内容,再通过代码读取具体的内容。
这里支持将具体的文件内容放到json里面,支持二进制与json文件的相互转换。
# Json ---> Binary
flatc --binary monster.fbs monsterdata.json
# Binary ---> Json
flatc --json --raw-binary monster.fbs -- monsterdata.bin
Reference: google.github.io/flatbuffers…