☰
FlatBuffers 编译器 `flatc` 完全指南:命令行用法、生成器选项与数据转换实战
2026/10/10 17:34:22 网站建设 项目流程

FlatBuffers 编译器flatc完全指南:命令行用法、生成器选项与数据转换实战

【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers

flatc是 FlatBuffers 生态的核心编译器,负责把.fbs模式定义(schema)翻译成 C++、Java、Go、Rust、TypeScript 等十余种语言的序列化代码,同时承担 JSON 与二进制 flatbuffer 之间的双向转换。本文以仓库官方文档 docs/source/flatc.md 为主体,结合 src/flatc_main.cpp、src/flatc.cpp 等源码实现,系统讲解flatc的命令行语法、全部生成器选项、gRPC 扩展选项及其底层调用链,帮助读者在真实项目中熟练使用这一工具。

flatc在 FlatBuffers 中的地位

FlatBuffers 是一种免解析、零拷贝的高效内存序列化库:数据被序列化后可直接从内存缓冲区中读取,无需中间解包步骤。而这一切的起点,就是flatc—— 它将模式定义转换为各语言的生成代码,让开发者可以在自己熟悉的语言中直接操作 FlatBuffers 结构。

flatc的可执行文件由本仓库源码编译而来。构建方式参见 docs/source/building.md,典型流程为:

cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release make -j

构建完成后即可得到flatc可执行文件。其主程序入口位于 src/flatc_main.cpp,核心流程是:通过FlatCompiler注册各语言代码生成器,解析命令行参数(ParseFromCommandLineArguments),最后调用flatc.Compile(options)完成整个编译过程。

命令行基本语法

flatc的调用形式如下(出自 docs/source/flatc.md):

flatc [ GENERATOR_OPTIONS ] [ -o PATH ] [- I PATH ] FILES... [ -- BINARY_FILES... ]

其中:

  • GENERATOR_OPTIONS:指定要为哪些语言生成代码,以及要启用/禁用的各种特性;
  • -o PATH:指定生成文件的输出目录,缺省时输出到当前目录;
  • -I PATH:指定被include的 schema 文件所在路径,缺省时默认为当前目录;
  • FILES...:一个或多个 schema 文件或数据文件,按命令行给出的顺序依次处理;
  • -- BINARY_FILES...:--之后的文件被当作二进制 flatbuffer 数据文件处理。

从源码 src/flatc.cpp 可以看到,参数解析逻辑正是围绕这一结构展开的:-o设置output_path,-I追加到include_directories列表,--被识别为文本输入与二进制输入的分隔符(options.binary_files_from = options.filenames.size(),见 src/flatc.cpp)。解析完成后会调用ValidateOptions做合法性校验,例如未指定任何生成器且未使用--conform/--annotate时会报错"no options: specify at least one generator."(src/flatc.cpp)。

输入文件:Schema 与数据文件

Schema 文件:指定语言生成器

当FILES...中是 schema 文件(.fbs)时,语言指定符决定为哪些语言生成代码。flatc支持的全部语言生成器如下(同时列出源码 src/flatc_main.cpp 中注册的短选项):

长选项短选项目标语言
--cpp-cC++
--java-jJava
--kotlin—Kotlin
--csharp-nC#
--go-gGolang
--python-pPython
--js—JavaScript
--ts-TTypeScript
--php—PHP
--dart-dDart
--lua-lLua
--lobster—Lobster
--rust-rRust
--swift—Swift
--nim—Nim

另外还有两个与语言代码生成密切相关的扩展选项:

  • --grpc:为指定语言额外生成 gRPC RPC 桩代码(并非所有语言都支持,具体见下文 gRPC 选项一节);
  • --jsonschema:生成 JSON Schema 文件(注册于 src/flatc_main.cpp)。

注意:原文档提示short-form 选项已被弃用,应尽量使用长选项形式。例如多语言一次生成:

flatc --cpp --go --rust monster.fbs

会同时为monster.fbs生成 C++、Go、Rust 三套代码。

数据文件:二进制与 JSON 互转

如果FILES...中包含数据文件,则可用以下选项在二进制与 JSON 之间互相转换:

  • --binary、-b:根据 JSON 数据生成包含序列化 flatbuffer 的二进制文件;
  • --json、-t:从序列化的二进制 flatbuffer 生成 JSON 文件。

原文档指出,这两个选项都要求先在FILES...列表中给出对应的 schema 文件。

JSON → 二进制:使用 schemamyschema.fbs序列化mydata.json中的数据:

flatc --binary myschema.fbs mydata.json

该命令会生成mydata_wire.bin文件,内含序列化后的 flatbuffer 数据。实际生成文件名由输入文件基名加_wire后缀构成,相关命名逻辑在 src/flatc.cpp(filebase = StripPath(StripExtension(filename)))与各生成器内部实现。

二进制 → JSON:使用 schemamyschema.fbs将二进制文件mydata.bin转换为 JSON:

flatc --json myschema.fbs -- mydata.bin

该命令会生成mydata.json。注意这里二进制文件放在--之后。如果该 schema 没有定义file_identifier(文件标识符),则需要加--raw-binary选项才能读取。

关于file_identifier:在 schema 中通过file_identifier "MYFI";声明(参见 docs/source/schema.md),标识符必须恰好 4 个字符,写入缓冲区偏移 4~7 字节处。源码 src/flatc.cpp 中可见:读取二进制文件时,若未加--raw-binary,flatc会强制校验二进制数据中的标识符与 schema 的file_identifier是否一致,不一致或 schema 未定义标识符都会直接报错——这正是原文档要求无标识符时使用--raw-binary的原因(该选项允许跳过校验,但也提示"对不匹配的 schema 使用可能崩溃")。

全部附加选项详解

以下选项完整继承自 docs/source/flatc.md 的 "Additional options" 章节,并补充了源码中的默认值与解析细节。

路径与输出控制

选项说明
-o PATH所有生成文件输出到 PATH(绝对路径或相对当前目录的相对路径)。省略时输出到当前目录。PATH 应以系统路径分隔符结尾,如/或\。
-I PATH遇到include语句时,按给定顺序尝试从这些路径加载被包含文件;全部失败(或未指定)时,回退到被解析 schema 文件所在目录的相对路径。
-M打印生成文件的 make 规则(而非直接生成代码),便于接入 Makefile 等构建系统。对应源码options.print_make_rules = true(src/flatc.cpp)。
--filename-suffix SUFFIX生成文件名的后缀,默认_generated。
--filename-ext EXTENSION生成文件的扩展名,默认语言相关(如 C++ 为h)。指定多语言时不应使用本选项。
--include-prefix PATH为生成的 include 语句添加路径前缀。
--keep-prefix保留 schema include 语句的原始前缀。
--file-names-only只把本次命令会生成的文件名逐行打印到 stdout,不实际生成文件,适合 CI 校验。对应options.file_names_only(src/flatc_main.cpp)。

JSON 输出控制

选项说明
--strict-json要求并生成严格 JSON(字段名加引号、表/向量无尾随逗号)。默认不要求引号、允许尾随逗号。
--allow-non-utf8允许非 UTF-8 输入通过解析器,并在 JSON 中输出非标准的\x转义(默认对非 UTF-8 输入报解析错误)。
--natural-utf8输出字符串时按人类可读的 UTF-8 形式展示(默认 UTF-8 字符输出为\uXXXX转义)。
--defaults-json写 JSON 时也输出值等于默认值的字段(对应output_default_scalars_in_json,src/flatc.cpp)。
--force-defaults从 JSON 生成二进制时,在二进制输出中显式写入默认值。
--force-empty从对象 API 表示序列化时,强制字符串与向量为空([]/"")而非 null。
--force-empty-vectors同上,但仅针对向量。
--flexbuffers与--binary、--json配合,改用无 schema 的 FlexBuffers 格式生成数据(对应use_flexbuffers,src/flatc.cpp)。
--json-nested-bytes允许在 JSON 中把nested_flatbuffer字段当作字节向量解析;未经 verifier 校验时不安全。

C++ 代码生成控制

选项说明
--no-prefix生成 C++ 时,枚举值不再以枚举类型名为前缀。
--scoped-enums生成 C++11 风格的作用域强类型枚举,同时隐含--no-prefix。源码中二者均置prefixed_enums = false(src/flatc.cpp)。
--no-emit-min-max-enum-values不生成作用域枚举/带前缀枚举的 MIN 与 MAX 枚举值。
--cpp-std CPP_STD选择 C++ 标准:c++0x(兼容旧编译器,如 VS2010)、c++11(默认)、c++17(实验性,使用 C++17 特性)。
--cpp-include在生成文件中额外添加一个#include。
--cpp-ptr-type T设置对象 API 的指针类型,默认std::unique_ptr。
--cpp-str-type T设置对象 API 的字符串类型,默认std::string。自定义类型必须支持T::c_str()、T::length()、T::empty(),且可由std::string构造(可用--cpp-str-flex-ctor改变该行为)。
--cpp-str-flex-ctor构造自定义字符串类型时不传std::string,而传(char* + length),支持高效甚至零拷贝构造。
--no-cpp-direct-copy不为 C++ 对象 API 生成直接拷贝方法。

对象 API(Object API)相关

对象 API 是比基础 API 更便于构造与修改的"对象化"接口,代价是额外分配对象、效率较低,原文档建议仅在其它选项无法满足时使用。

选项说明
--gen-object-api生成额外的对象化 API。
--gen-compare为对象 API 类型生成operator==。
--object-prefix自定义 C++ 对象 API 类名前缀。
--object-suffix自定义 C++ 对象 API 类名后缀(源码默认值为"T",见 src/flatc.cpp)。

其它语言相关选项

选项说明
--gen-mutable生成额外的非 const 访问器,支持原地修改 FlatBuffers。
--gen-name-strings为 C++ 生成类型名函数。
--gen-nullable为 C++ 指针添加 Clang_Nullable,或为 Java 添加@Nullable。
--gen-generated为 Java 添加@Generated注解。
--gen-jvmstatic为 Kotlin companion object 中的方法添加@JvmStatic注解,便于 Java 互操作。
--gen-onefile为 C#、Go、Java、Kotlin 与 Python 生成单一输出文件。
--gen-includes已弃用(现为默认行为);如需旧行为(不含 include 语句),使用--no-includes。
--no-includes不为被包含 schema 生成 include 语句(C++ / Python)。
--gen-all不仅为当前 schema 文件生成代码,还为其 include 的所有文件生成代码;若语言默认单文件输出(如 C++ 和 JS),则所有代码进入同一文件。
--go-namespace覆盖 Golang 生成的命名空间。
--go-import覆盖 Golang 中 flatbuffers 的导入路径,默认github.com/google/flatbuffers/go。
--cs-global-alias为所有生成的 C# 类与结构体添加global::前缀。
--python-no-type-prefix-suffix跳过生成带类型名前缀/后缀的 Python 函数。
--python-typing生成 Python 类型注解。
--python-decode-obj-api-strings自动以 UTF-8 解码 Python 对象 API 中的 bytes 字符串。

反射与校验

选项说明
--schema序列化 schema 而非 JSON(配合-b使用):输出对应 reflection/reflection.fbs 的二进制 schema(BFBS)文件,加载该文件是反射功能的基础。源码中置schema_binary = true(src/flatc.cpp)。
--bfbs-comments为二进制 schema 文件添加文档注释。
--reflect-types为代码生成添加最小类型反射。
--reflect-names添加最小类型/名称反射。
--root-type T选择或覆盖默认的root_type。源码中会在生成代码后调用parser->SetRootType(...),且要求根类型必须是 table(src/flatc.cpp)。
--conform FILE指定一个 schema,要求后续 schema 必须是它的演进版本,否则报错。用于检查 schema 修改是否违反演进规则。
--conform-includes PATH为--conform指定的 schema 提供 include 路径。

二进制读取与 Protobuf 转换

选项说明
--raw-binary允许读取不含file_identifier的二进制文件。schema 不匹配时可能导致flatc崩溃,请谨慎使用。
--size-prefixed输入二进制为带大小前缀的缓冲区。
--require-explicit-ids解析 schema 时,要求字段必须显式指定id: x。
--proto将输入视为.proto文件(Protocol Buffers),输出对应的.fbs文件。目前支持:package、message、enum、嵌套声明、import(路径用-I)、extend、oneof、group;不支持但会跳过(不报错):option、service、extensions及大部分其它内容。
--oneof-union将.proto的oneof翻译为 flatbuffer union。

另有--no-warnings(抑制所有警告信息),以及一个源码中注册但原文档表格未列出的实用选项--annotate SCHEMA:按给定 schema 对二进制文件生成带注释的文本视图(见 src/flatc.cpp 与AnnotateBinaries实现,src/flatc.cpp)。

附加 gRPC 选项

--grpc会为指定语言生成 gRPC 接口。除 grpc/README.md 中给出的完整 gRPC 示例外,flatc还针对不同语言提供了以下附加选项:

选项适用范围说明
--grpc-filename-suffixC++生成文件的额外后缀。例如 C++ 下用--grpc-filename-suffix=.fbs会生成{name}.fbs.h与{name}.fbs.cc。
--grpc-additional-headerC++在生成文件中额外包含的头文件。
--grpc-search-pathC++gRPC 运行时路径的可选前缀。例如--grpc-search-path=some/path会生成如下 include:
#include "some/path/grpcpp/impl/codegen/async_stream.h" #include "some/path/grpcpp/impl/codegen/async_unary_call.h" #include "some/path/grpcpp/impl/codegen/method_handler.h" ...

|--grpc-use-system-headers| C++ | 生成#include <header>而非#include "header.h"。可用--no-grpc-use-system-headers取反。示例: |

#include <some/path/grpcpp/impl/codegen/async_stream.h> #include <some/path/grpcpp/impl/codegen/async_unary_call.h> #include <some/path/grpcpp/impl/codegen/method_handler.h> ...

|--grpc-python-typed-handlers| Python | 生成使用已生成 Python 类(而非原始字节)处理请求/响应的类型化 handler。 |

从源码 src/flatc.cpp 可以看到 gRPC 代码生成的具体调用链:每个已注册的生成器在完成常规代码生成后,若grpc_enabled为真,会继续调用code_generator->GenerateGrpcCode(...);若该语言未实现 gRPC 生成器,则给出"GRPC interface generator not implemented for ..."警告(如 src/flatc.cpp 所示)。这正是原文档注明"--grpc并非所有语言都可用"的源码依据。

从源码理解flatc的编译流水线

将命令行参数与源码对照,可以还原flatc一次完整调用的内部流程(详见 src/flatc.cpp 的GenerateCode):

  1. 加载与分类输入:逐个读取FILES...,依据扩展名判断类型——.fbs/.proto为 schema 文本、.bfbs为二进制 schema、其余按数据文件处理;位于--之后的文件强制视为二进制 flatbuffer。
  2. 解析 schema:通过Parser解析 schema 文本,include语句按-I指定路径顺序查找(参见 include/flatbuffers/flatc.h 中的ParseFile)。
  3. 合法性校验:检查循环结构依赖(HasCircularStructDependency),以及--conform演进一致性(ConformTo)。
  4. BFBS 序列化:若某个生成器依赖二进制 schema(如 Lua、Nim 通过 BFBS 生成),先parser->Serialize()得到 BFBS 缓冲区再交给生成器。
  5. 逐生成器产出代码:每个生成器按filebase计算输出文件名,写入-o指定目录;-M模式下则只打印 make 规则。
  6. gRPC 扩展:启用--grpc时对每个生成器追加调用GenerateGrpcCode。

参数选项的数据结构定义于 include/flatbuffers/idl.h 的IDLOptions(如strict_json、scoped_enums、filename_suffix、force_defaults、python_typing等),命令行解析时逐项写入,最终贯穿整个编译过程,这正是各选项语义能够精确落实到每个生成器的原因。

常见用法速查

以下汇总几种典型场景,可直接复制使用:

# 1. 为多语言生成代码 flatc --cpp --python --ts monster.fbs # 2. 指定输出目录与被包含 schema 的搜索路径 flatc --cpp -o build/generated -I include/schemas monster.fbs # 3. JSON 数据序列化为二进制 flatbuffer flatc --binary myschema.fbs mydata.json # 4. 二进制 flatbuffer 反序列化为 JSON(无 file_identifier 时加 --raw-binary) flatc --json myschema.fbs -- mydata.bin # 5. 生成对象 API 并开启 C++17 特性 flatc --cpp --gen-object-api --cpp-std c++17 monster.fbs # 6. 检查 schema 演进是否兼容 flatc --conform old_schema.fbs --conform-includes include new_schema.fbs # 7. 仅查看会生成哪些文件(CI 校验用) flatc --cpp --file-names-only monster.fbs

小结

flatc是整个 FlatBuffers 生态的"编译器枢纽":它既是把 schema 翻译为 15+ 种语言代码的代码生成器,也是 JSON 与二进制数据互转的转换器,还能产出二进制 schema(BFBS)、校验 schema 演进、甚至把.proto翻译为.fbs。本文完整继承了官方文档 docs/source/flatc.md 的全部选项说明,并结合 src/flatc_main.cpp 与 src/flatc.cpp 的源码实现,揭示了每个选项背后的参数解析与编译流水线。实际使用中,建议优先采用长选项形式,并善用flatc --help(对应GetUsageString,src/flatc.cpp)随时查看最新、最完整的选项清单。

【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询