flatbuffer と protobuf の個人的な比較: flatbuffer は protobuf よりも一桁使いやすく、お互いに出会うには遅すぎます。スキーマ ファイルの作成とコンパイル、buf ファイルでの Python/C++ の操作、サードパーティの依存関係の導入とフラットバッファ コードの構築に至るまで、すべてが非常にシンプルかつスムーズです。
コードライブラリ
GitHub - google/ flatbuffers: FlatBuffers: メモリ効率の高いシリアル化ライブラリ
チュートリアル
コンパイルオプション
flatbuffer コードをビルドせずに、プリコンパイルされたバイナリ flatc コンパイル済みスキーマ ファイルをコード ライブラリにダウンロードできます。
Scama ファイルをコンパイルして C++ 定義を生成する
flatc --cpp --gen-object-api ./schema.fbs
ヘッダー ファイル schema_generated.h を生成します。
Scama ファイルをコンパイルして Python 定義を生成する
flatc --python --gen-object-api ./schema.fbs
pip install flatbuffers==2.0.0 #モデルを操作するために上でコンパイルした Python コードと組み合わせて、対応するバージョンの pip パッケージをインストールします
--gen-object-api オプションを追加すると、ネイティブ型に基づいてオブジェクトを定義し、パックとアンパックに基づいて flatbuf オブジェクトを作成し、シリアル化と逆シリアル化を実行できるため、非常に便利です。
配列は、Python と対話するときに numpy 変換をサポートしており、非常に便利です。
フラットバッファの使用 - He Nanren - Blog Garden
ユーザーのソース コードは、生成されたファイルをインクルードするだけでよく、 flatbuffers/include/ のヘッダー ファイルとともに使用でき、so ファイルを生成するために flatbuffer をコンパイルする必要がなく、protobuf よりもはるかに便利です。flatbuf を使用すると、コンパイル済みの flatc バイナリを使用するだけでなく、依存ライブラリやその他のサードパーティをコンパイルする必要もありません。
flatc は、バイナリでシリアル化された flatbuf ファイルを json ファイルに変換します。
# flatc --raw-binary -t <path to fbs schema file> -- <path to flatbuffer binary file>
../flatc --raw-binary -t monster.fbs -- Monster.bin
FlatBuffers反射 - HarmonyHu’s Blog
flac がソース コードを生成するとき、--gen-object-api を追加する必要があります。その後、
1) 各テーブルはオブジェクト構造 (T 末尾文字) を生成し、この構造はデータ操作を直接実行できます;
2) UnPack を各テーブルに追加します。 /UnpackTo/Pack メソッドは、オブジェクト構造とテーブル構造の間で変換します。
オブジェクトは CreateXXX メソッドを使用して作成できます。
手順
// 反序列化成object结构体
auto moster = GetMoster(flatbuffer);
MonsterT * monsterObj = moster->UnpackTo();
...
delete monsterObj;
// Autogenerated class from table Monster.
MonsterT monsterobj;
// Deserialize from buffer into object.
GetMonster(flatbuffer)->UnPackTo(&monsterobj);
// 序列化成table结构体
MonsterT monsterObj;
monsterObj->name = "Bob";
FlatBufferBuilder builder;
Pack(builder, &monsterObj);
添付ファイル: flatc オプション
--cpp: xxxx_generate.h の C++ ソース ファイルを生成します
--gen-mutable: 各テーブルは変更可能なメソッドを生成します
--gen-name-strings: 各テーブルは GetFullyQualifiedName メソッドを生成し、パスを返します名前 (例: MySample.Monster
--reflect-names): 各テーブルは MiniReflectTypeTable メソッドを生成し、各メンバー名とメンバー属性を含む TypeTable * を返します
--gen-object-api: 各テーブルはオブジェクト クラスを生成し、パックを生成しますおよび unpack メソッド (シリアル化と逆シリアル化用)
シリアル化と逆シリアル化
連載
MonsterT monsterobj;
// Update object directly like a C++ class instance.
cout << monsterobj.name; // This is now a std::string!
monsterobj.name = "Bob"; // Change the name.
// Serialize into new flatbuffer.
FlatBufferBuilder fbb;
fbb.Finish(Monster::Pack(fbb, &monsterobj));
uint8_t *buf = builder.GetBufferPointer();
int size = builder.GetSize(); // Returns the size of the buffer that GetBufferPointer() points to.
逆シリアル化
インライン const MyGame::Sample::Monster *GetMonster(const void *buf)
Pythonロードモデル
from MyGame.Sample.Monster import Monster as example
# import flatbuffers
buf = open('Monster.bin', 'rb').read()
buf = bytearray(buf)
monster = example.GetRootAsMonster(buf, 0)
with open('Monster.bin', 'rb') as f:
buf = f.read()
buf = bytearray(buf)
monster = Monster.GetRootAsMonster(buf, 0)
monster_t = MonsterT.InitFromObj(monster)
builder = flatbuffers.Builder()
lite_graph = graph_t.Pack(builder)
builder.Finish(lite_graph)
buf = builder.Output()
with open(out_model_path, mode="wb") as f:
f.write(buf)
フラットバッファの使用 - He Nanren - Blog Garden
スキーマファイル
スキーマファイルの開発方法
モデル ファイル、バイナリ ファイル、テキスト ファイルを生成および保存、ロードする方法
他の fbs ファイルを fbs に含めることもできます
「xxx.fbs」を含めます。
複数の root_type を定義するには、元のスキーマに基づいて新しい root_type を作成し、以前のものを参照して、新しい root_type を定義することを検討できます。
include "schema.fbs";
namespace xxx;
root_type yyy;