flatbuffer下載地址:https://github.com/google/flatbuffershtml
flatbuffer官方使用文檔:https://google.github.io/flatbuffers/index.html#flatbuffers_overviewgit
flatbuffer官方測試用例:https://google.github.io/flatbuffers/flatbuffers_guide_use_cpp.htmlgithub
引用官方測試使用的IDL編程
1 // Example IDL file for our monster's schema. 2 namespace MyGame.Sample; 3 enum Color:byte { Red = 0, Green, Blue = 2 } 4 union Equipment { Weapon } // Optionally add more tables. 5 struct Vec3 { 6 x:float; 7 y:float; 8 z:float; 9 } 10 table Monster { 11 pos:Vec3; // Struct. 12 mana:short = 150; 13 hp:short = 100; 14 name:string; 15 friendly:bool = false (deprecated); 16 inventory:[ubyte]; // Vector of scalars. 17 color:Color = Blue; // Enum. 18 weapons:[Weapon]; // Vector of tables. 19 equipped:Equipment; // Union. 20 path:[Vec3]; // Vector of structs. 21 } 22 table Weapon { 23 name:string; 24 damage:short; 25 } 26 root_type Monster;
利用flatc.exe生成IDL對應的樁代碼,命令格式爲ide
1 flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] [ -S ] FILES... [ -- FILES...]
1 flatc --cpp monster.fbs
flatbuffer使用模板編程,僅生成h文件。對應的文件名爲filename_generated.h。這裏生成monster_generated.h文件。測試
Table是FlatBuffer定義的主要數據類型,一個Table包含一個名稱(如2.1的Monster),以及一組字段(如2.1的Monster)。每一個字段由名稱、類型及默認值組成。ui
FlatBuffer每一個字段都是可選的,這由FlatBUffer的線性實現機制決定:空閒字段僅填充默認佔位值,而不佔用分配size。google
Struct只包含數值類型與其餘struct,與Table相比,Struct使用更少的存儲空間以及更快的訪問速度。spa
內建的數值類型有:scala
內建的非數值類型有:
定義了一系列的命名常量,能夠給定默認值。第一個變量的默認值爲0。
能夠定義嵌套的namespace,用.分割。
定義序列化的root table或者struct。
對2.1例子的序列化和反序列化過程實如今sample_binary.cpp。
1 // Build up a serialized buffer algorithmically: 2 flatbuffers::FlatBufferBuilder builder; //申請一個flatbuffer 3 4 // First, lets serialize some weapons for the Monster: A 'sword' and an 'axe'. 5 auto weapon_one_name = builder.CreateString("Sword"); //在buffer中申請string 6 short weapon_one_damage = 3; 7 8 auto weapon_two_name = builder.CreateString("Axe"); //在buffer中申請string 9 short weapon_two_damage = 5; 10 11 // Use the `CreateWeapon` shortcut to create Weapons with all fields set. 12 auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage); //樁代碼中實現 13 auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage); // 14 15 // Create a FlatBuffer's `vector` from the `std::vector`. 16 std::vector<flatbuffers::Offset<Weapon>> weapons_vector; 17 weapons_vector.push_back(sword); 18 weapons_vector.push_back(axe); 19 auto weapons = builder.CreateVector(weapons_vector); //在buffer中序列化vector 20 21 // Second, serialize the rest of the objects needed by the Monster. 22 auto position = Vec3(1.0f, 2.0f, 3.0f); 23 24 auto name = builder.CreateString("MyMonster"); 25 26 unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 27 auto inventory = builder.CreateVector(inv_data, 10); 28 29 // Shortcut for creating monster with all fields set: 30 auto orc = CreateMonster(builder, &position, 150, 80, name, inventory, 31 Color_Red, weapons, Equipment_Weapon, axe.Union()); 32 33 builder.Finish(orc); // Serialize the root of the object. //序列化對象root 34 35 // We now have a FlatBuffer we can store on disk or send over a network. 36 37 // ** file/network code goes here :) **
1 // access builder.GetBufferPointer() for builder.GetSize() bytes 2 3 // Instead, we're going to access it right away (as if we just received it). 4 5 // Get access to the root: 6 auto monster = GetMonster(builder.GetBufferPointer()); //獲取根對象指針 7 8 // Get and test some scalar types from the FlatBuffer. 9 assert(monster->hp() == 80); 10 assert(monster->mana() == 150); // default 11 assert(monster->name()->str() == "MyMonster"); 12 13 // Get and test a field of the FlatBuffer's `struct`. 14 auto pos = monster->pos(); 15 assert(pos); 16 assert(pos->z() == 3.0f); 17 (void)pos; 18 19 // Get a test an element from the `inventory` FlatBuffer's `vector`. 20 auto inv = monster->inventory(); 21 assert(inv); 22 assert(inv->Get(9) == 9); 23 (void)inv; 24 25 // Get and test the `weapons` FlatBuffers's `vector`. 26 std::string expected_weapon_names[] = { "Sword", "Axe" }; 27 short expected_weapon_damages[] = { 3, 5 }; 28 auto weps = monster->weapons(); 29 for (unsigned int i = 0; i < weps->size(); i++) { 30 assert(weps->Get(i)->name()->str() == expected_weapon_names[i]); 31 assert(weps->Get(i)->damage() == expected_weapon_damages[i]); 32 } 33 (void)expected_weapon_names; 34 (void)expected_weapon_damages; 35 36 // Get and test the `Equipment` union (`equipped` field). 37 assert(monster->equipped_type() == Equipment_Weapon); 38 auto equipped = static_cast<const Weapon *>(monster->equipped()); 39 assert(equipped->name()->str() == "Axe"); 40 assert(equipped->damage() == 5); 41 (void)equipped;
https://www.jianshu.com/p/fa999434776a