FlatBuffers 如何构建 flatc 并从 schema 完成首次代码生成与序列化?
【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers
本文对应的任务是 FlatBuffers 的完整首发流程:从源码构建编译器flatc,用它把一个.fbsschema 生成目标语言的代码,再用生成代码配合FlatBufferBuilder完成第一次数据序列化,并从序列化结果中读回数据做校验。文档给出的默认构建与使用路径面向 Unix 环境(CMake + Make),Windows 与 MacOS 的等价命令在文中单独标出。
前置条件
- 构建工具是 CMake。CMakeLists.txt 中声明
cmake_minimum_required(VERSION 3.8...3.25.2),即 CMake 版本需落在该区间内。 - 编译出
flatc由 CMake 选项FLATBUFFERS_BUILD_FLATC控制,该选项默认为ON,所以按默认配置构建时不需要额外开启。 - 编译器方面,building.md 提到若要用
clang替代gcc,可以通过环境变量指定,例如CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -G "Unix Makefiles"。
第一步:构建 flatc
在仓库根目录执行配置与编译。quick_start.md 给出的最简路径是:
cmake -G "Unix Makefiles" make -jbuilding.md 的正式构建命令建议带上 Release 类型:
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release make -j其他平台的对应方式(来自 building.md):
# Windows cmake -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=Release msbuild.exe FlatBuffers.sln# MacOS cmake -G "Xcode" -DCMAKE_BUILD_TYPE=Release xcodebuild -toolchain clang -configuration Release构建成功后,构建目录中会产出可执行的flatc。tutorial.md 也给出了只编译该目标的变体:cmake -G "Unix Makefiles"之后执行make flatc,适合只想拿编译器的场景。如果后续要在 CI 中强制严格告警模式,可以用-DFLATBUFFERS_STRICT_MODE=ON重新配置(building.md)。
第二步:定义 schema(.fbs)
schema 文件是flatc的输入。quick_start.md 用的最小示例如下,可以存为monster.fbs:
table Monster { name:string; health:int; } root_type Monster;其中root_type声明了 flatbuffer 的入口 table 类型。仓库中还有更完整的参考 schema samples/monster.fbs,包含 namespace、enum、union、struct 和默认值等写法,字段细节可在 tutorial.md 的带注释版本里逐条查看。
第三步:用 flatc 生成代码
构建完成后,在 schema 所在目录调用生成的flatc(flatc.md 的调用形式):
./flatc [ GENERATOR_OPTIONS ] [ -o PATH ] [ -I PATH ] FILES...以 quick_start.md 的命令为例,同时生成 C++ 与 Rust 代码:
./flatc --cpp --rust monster.fbs该命令会生成monster_generated.h和monster_generated.rs两个文件。语言标志在 flatc.md 中列出了完整清单:--cpp、--java、--kotlin、--csharp、--go、--python、--js、--ts、--php、--dart、--lua、--lobster、--rust、--swift、--nim。首次使用时按需选择目标语言即可。
两个常用路径参数:
-o PATH:指定生成文件输出目录,未指定时默认输出到当前目录,路径应以系统路径分隔符结尾。-I PATH:指定include语句引用的 schema 文件查找路径,按给出顺序尝试;都不存在时回退到当前 schema 文件所在路径。
另外,--file-names-only选项可以只打印本次命令将会生成的文件列表而不真正生成,适合先在 CI 中核对产物清单。
第四步:用生成代码完成序列化与读回
生成文件包含序列化和反序列化两侧所需的全部 API。以 C++ 为例,quick_start.md 的最小示例流程如下(对应上一步的最小 schema):
#include "flatbuffers.h" #include "monster_generated.h" int main() { // Used to build the flatbuffer FlatBufferBuilder builder; // Auto-generated function emitted from `flatc` and the input // `monster.fbs` schema. auto monster = CreateMonsterDirect(builder, "Abominable Snowman", 100); // Finalize the buffer. builder.Finish(monster); // Get a pointer to the flatbuffer. const uint8_t* flatbuffer = builder.GetBufferPointer(); // Get a view of the root monster from the flatbuffer. const Monster snowman = GetMonster(flatbuffer); // Access the monster's fields directly. ASSERT_EQ(snowman->name(), "Abominable Snowman"); ASSERT_EQ(snowman->health(), 100); }关键点:CreateMonsterDirect是flatc根据 schema 自动生成的函数;builder.Finish(monster)收尾后,用builder.GetBufferPointer()拿到序列化缓冲区的指针;再用GetMonster(flatbuffer)从缓冲区读回根对象。文中对字段name、health的断言值是文档示例中写入的数据,用于说明读回结果应与写入值一致。
如果直接使用完整的 samples/monster.fbs 作为 schema,仓库提供了完整的 C++ 参照程序 samples/sample_binary.cpp:它先用builder.CreateString序列化武器名字符串,用生成的CreateWeapon创建两个武器,再经CreateVector、CreateMonster组装出完整 Monster 并builder.Finish(orc),随后用GetMonster(builder.GetBufferPointer())读回,逐字段用assert校验hp、mana、name、inventory、weapons、equipped等,全部通过时程序打印(文档示例输出):
The FlatBuffer was successfully created and verified!C++ 项目引入 FlatBuffers 的方式在 building.md 中有明确说明:C++ 通常没有需要单独编译的 runtime,核心是单头文件include/flatbuffers/flatbuffers.h,把include目录加入头文件搜索路径即可;如果需要运行时加载 schema 或把文本解析为二进制缓冲区,还需引入include/flatbuffers中的其余头文件,并编译链接src/idl_parser.cpp(想把二进制转回文本时再链接src/idl_gen_text.cpp)。若你的工程本身使用 CMake,也可以用add_subdirectory把 FlatBuffers 源码作为子目录直接编进项目,与主工程共用同一套编译和链接设置。
可选分支:用 flatc 直接做数据文件转换
除了生成代码后在程序内序列化,flatc本身也能在命令行完成 JSON 与二进制的互转(flatc.md)。用 schemamyschema.fbs把 JSON 数据mydata.json序列化为二进制:
flatc --binary myschema.fbs mydata.json会生成mydata_wire.bin;反向把二进制转回 JSON:
flatc --json myschema.fbs -- mydata.bin两个方向的共同限制:对应 schema 文件必须列在参数列表的最前面。另外,如果 schema 没有定义file_identifier,读取二进制时需要附加--raw-binary选项。
限制与下一步
- 生成代码的文件名后缀默认是
_generated(--filename-suffix可改),扩展名随语言而定,例如 C++ 为.h。 - 序列化缓冲区可以存盘或走网络传输,读回端不必与写入端同语言;跨语言读取示例见 tutorial.md,schema 演进规则见 docs/source/evolution.md。
- 各语言的完整引入、Builder 用法与读写细节在 tutorial.md 中按语言分节给出,覆盖从 C++、C#、Go、Java、Kotlin、Python、Rust、TypeScript 到 Lua、Nim 等十余种语言。
【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考