在 Lua 中使用 FlatBuffers:读写序列化数据的完整指南

发布时间:2026/9/10 23:14:39

在 Lua 中使用 FlatBuffers:读写序列化数据的完整指南 在 Lua 中使用 FlatBuffers读写序列化数据的完整指南【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers导读本文以 FlatBuffers 官方文档中 Lua 语言支持章节docs/source/languages/lua.md为骨架系统讲解如何在 Lua 中通过flatc --lua生成的代码读写 FlatBuffer 二进制数据。你将掌握 Lua 运行时库的目录结构与模块构成、测试环境的搭建与运行方式、读取 FlatBuffer 的核心代码模式以及 Builder/View 两大组件在源码层面的工作原理并了解 Lua 侧文本解析能力的边界与替代方案。开始之前前置知识准备在深入 Lua 用法之前建议先按顺序完成以下铺垫阅读 docs/source/tutorial.md它给出了所有受支持语言含 Lua通用的 FlatBuffers 完整使用教程本文只讨论 Lua 特有的细节阅读 docs/source/building.md 构建flatc编译器熟悉 docs/source/flatc.mdschema 编译器用法与 docs/source/schema.mdschema 编写规范。FlatBuffers Lua 库代码位置Lua 运行时库全部位于仓库的lua/目录下顶层入口为 lua/flatbuffers.lua。该入口模块是一个极薄的封装聚合了四个核心子模块local m {} m.Builder require(flatbuffers.builder).New m.N require(flatbuffers.numTypes) m.view require(flatbuffers.view) m.binaryArray require(flatbuffers.binaryarray) return mflatbuffers.builder负责写入方向等价于 C 的FlatBufferBuilder提供New(initialSize)构造器见 lua/flatbuffers/builder.luaflatbuffers.view负责读取方向封装了对已序列化缓冲区的字段定位、字符串与向量访问等底层操作见 lua/flatbuffers/view.luaflatbuffers.numTypes定义全部标量类型int8/16/32/64、uint8/16/32/64、float32/64、bool以及 FlatBuffers 内部偏移类型UOffsetTuint32、VOffsetTuint16、SOffsetTint32每个类型都带有bytewidth、取值范围与Pack/Unpack序列化原语见 lua/flatbuffers/numTypes.luaflatbuffers.binaryarray底层字节容器。构造时既可按整数指定初始容量构建模式也可直接接收一个 Luastring读取模式见 lua/flatbuffers/binaryarray.lua。此外lua/flatbuffers/compat.lua负责运行时版本适配它根据_VERSION自动选择compat_5_1.lua、compat_luajit.lua或compat_5_3.lua其中 5.3/5.4 使用原生的string.pack/string.unpack而 5.1 与 LuaJIT 则提供等价的兼容实现见 lua/flatbuffers/compat.lua。从源码结构看该库对 Lua 5.15.4 及 LuaJIT 均做了适配。测试 FlatBuffers Lua 库Lua 库的测试代码位于tests/目录下主测试文件tests/luatest.lua覆盖读写两端的核心场景运行脚本tests/LuaTest.sh。运行方式在仓库根目录执行bash tests/LuaTest.sh脚本会依次探测luajit、lua5.1、lua5.2、lua5.3、lua5.4中已安装的解释器并对每个可用版本运行luatest.lua见 tests/LuaTest.sh。前置要求本机需安装 Lua 5.3 与 LuaJIT仓库文档原注。测试覆盖了什么从 tests/luatest.lua 的测试清单可以看到核心用例测试验证内容sizePrefix带/不带 size prefix 的FinishSizePrefixed与Finish构建、读取往返一致fbbClearBuilder:Clear()复用后构建结果与全新 Builder 完全一致输出字节相同testCanonicalData直接读取仓库自带的 tests/monsterdata_test.mon 规范二进制文件testCreateEmptyString构建空字符串不会触发死循环读取返回getRootAs_canAcceptStringGetRootAsMonster可直接接收 Luastring内部自动转换为 binary arraytestAccessByteVectorAsString将 byte 向量以字符串形式切片访问InventoryAsString运行结束后会打印形如# of test passed: N / N (100.00%)的汇总。若传入benchmark参数lua luatest.lua benchmark还会追加构建/读取性能基准输出格式如built 10000 512-byte flatbuffers in 1.23sec: 8.13/msec, 4.16MB/sec见 tests/luatest.lua。使用 FlatBuffers Lua 库Lua 侧同时支持读取与写入FlatBuffers。总体流程分两步先用flatc --lua从 schema 生成 Lua 类再在代码中同时 require FlatBuffers 运行时库与生成代码。第一步生成 Lua 代码flatc --lua monster.fbs生成产物示例可参考仓库自带的 samples/lua/MyGame/Sample/Monster.lua每个 table 生成一个模块包含New()/GetRootAsMonster(buf, offset)对象构造与根对象解析读取方法如Monster_mt:Hp()、Monster_mt:Name()、Monster_mt:Inventory(j)写入辅助方法如Monster.Start(builder)、Monster.AddName(builder, name)、Monster.End(builder)其中Add*系列会携带 schema 中定义的默认值例如AddHp默认 100、AddMana默认 150见 samples/lua/MyGame/Sample/Monster.lua。第二步读取一个 FlatBuffer 二进制文件先 require 运行时库与生成代码再把二进制文件读入 Luastring交给生成的GetRootAsMonster函数-- require the library local flatbuffers require(flatbuffers) -- require the generated code local monster require(MyGame.Sample.Monster) -- read the flatbuffer from a file into a string local f io.open(monster.dat, rb) local buf f:read(*a) f:close() -- parse the flatbuffer to get an instance to the root monster local monster1 monster.GetRootAsMonster(buf, 0)随后使用冒号:语法访问成员数据-- use the : notation to access member data local hp monster1:Hp() local pos monster1:Pos()值得说明的是GetRootAsMonster的第一个参数既可以是 Luastring也可以是flatbuffers.binaryArray对象。view.New内部会对传入的string自动做binaryarray.New(buf)转换见 lua/flatbuffers/view.lua这也是luatest.lua中getRootAs_canAcceptString测试所验证的行为。当需要精细控制偏移例如跳过 size prefix时可显式构造 binary array 并传入偏移量local ba flatbuffers.binaryArray.New(buf) local mon monster.GetRootAsMonster(ba, 4) -- 跳过 4 字节 size prefix写入一个 FlatBuffer写入方向使用flatbuffers.Builder。以 tests/luatest.lua 中的generateMonster为例核心调用链为StartObject→CreateString/StartVectorPrepend*EndVector→Add*→EndObject→Finish→Outputlocal b flatbuffers.Builder(0) -- 初始容量 0内部自动增长 local str b:CreateString(MyMonster) -- 先构建字符串 monster.Start(b) -- StartObject(字段数) monster.AddHp(b, 80) -- 与默认值不同时才写入 slot monster.AddName(b, str) local mon monster.End(b) -- 结束对象并写 vtable b:Finish(mon) -- 完成整个 buffer local buf b:Output() -- 取最终字节串生成代码中的Add*方法如monster.AddName实际调用的是 Builder 的PrependUOffsetTRelativeSlot、PrependStructSlot或PrependInt16Slot等 slot 写入接口见 samples/lua/MyGame/Sample/Monster.lua。这些接口遵循 FlatBuffers 的默认值优化只有当写入值与 schema 默认值不同时才占用空间见 lua/flatbuffers/builder.lua 的PrependSlot实现从而进一步压缩体积。Builder 的底层工作原理从源码看lua/flatbuffers/builder.lua 完整实现了与 C 版本对齐的构建算法几个关键点从后往前构建head指针初始指向缓冲区末尾Place每次把数据写到head之前lua/flatbuffers/builder.lua对齐与扩容Prep通过compat.GetAlignSize计算填充缓冲区不足时按倍增策略增长硬上限为MAX_BUFFER_SIZE 0x800000002 GBlua/flatbuffers/builder.lua、lua/flatbuffers/builder.luavtable 去重WriteVtable会把新对象的 vtable 与已写入的 vtable 逐一比对相同则复用已有 vtable 的偏移lua/flatbuffers/builder.luaBuilder 复用Clear()不会清空底层字节数组而是复用其空间并将head重置到末尾适合批量构建场景lua/flatbuffers/builder.luafbbClear测试专门验证了这一点Finish 家族Finish、FinishSizePrefixed、FinishWithIdentifier、FinishSizePrefixedWithIdentifier四个变体分别对应是否带 4 字节 size prefix 与 4 字节 file identifierlua/flatbuffers/builder.lua。读取侧的底层支撑view 与 numTypes所有生成代码的读取方法都建立在 lua/flatbuffers/view.lua 之上view:Offset(vtableOffset)按字段在 vtable 中的偏移查找字段位置字段未写入时返回 0lua/flatbuffers/view.luaview:String(off)、view:Vector(off)、view:VectorLen(off)分别解析字符串、定位向量元素起始、读取向量长度view:GetSlot(slot, d, flags)带默认值的通用字段读取off 0时直接返回默认值dlua/flatbuffers/view.lua。数值解码则由numTypes完成它通过 Lua 5.3 的string.pack/string.unpack以及小端格式符如I4、i8、f、d实现跨版本的字节打包与解包见 lua/flatbuffers/numTypes.lua。对 Lua 5.1/LuaJITcompat层提供等价的 pack/unpack 实现保证同一套运行时库能在不同 Lua 版本下工作。文本解析Text Parsing的限制需要明确的是Lua 侧目前不支持直接解析文本格式——既不能解析 schema也不能直接解析 JSON。如果确有文本解析需求官方建议的替代路径是通过 SWIG 或 ctypes 调用 C 的解析器即flatc背后的idl_parser实现具体细节请参考 C 相关文档docs/source/flatc.md 中关于 JSON 转换与 schema 解析的部分。在实际项目中常见的做法是在构建或发布阶段使用flatc将 JSON 转换为二进制 FlatBuffer如仓库测试中的 tests/monsterdata_test.mon 即由 tests/monsterdata_test.json 生成运行时 Lua 端只负责高效地读取/写入二进制数据从而绕开 Lua 侧文本解析的空缺。总结Lua 运行时库位于 lua/ 目录由flatbuffers.lua统一导出 Builder、view、numTypes、binaryArray 四个子模块用flatc --lua生成类后读取只需require(flatbuffers) 生成模块 GetRootAs*写入则通过Builder的Start/Add/End/Finish调用链完成测试通过 tests/LuaTest.sh 一键运行支持 Lua 5.15.4 与 LuaJIT并可用benchmark参数做性能基准Lua 侧暂不支持 schema/JSON 文本解析需借助 C 解析器或预先离线转换二进制数据。【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/10 23:14:39

「AI Agent 全栈开发 50 讲」——从本地模型部署到多智能体系统,一年省 87 万 第 18 课 | 报告自动生成:python-docx + matplotlib 生成 Word 周报

第 18 课 | 报告自动生成:python-docx matplotlib 生成 Word 周报第 17 课 LLM 生成了洞察,但洞察是 JSON 数据——老板要的是排版精美的 Word 文档。这节课,我们用 python-docx 和 matplotlib 把数据变成直接能发的周报。一、业务价值&…

2026/9/10 23:49:43

Tracy Profiler 快速上手实战指南:4步定位游戏掉帧元凶

Tracy Profiler 快速上手实战指南:4步定位游戏掉帧元凶 【免费下载链接】tracy Frame profiler 项目地址: https://gitcode.com/GitHub_Trending/tr/tracy 你正在跑一个游戏,画面突然卡了一瞬,重跑一遍问题又消失了,日志里…

2026/9/10 23:49:42

SeaTunnel与Gravitino集成实现元数据自动化管理

1. 项目概述:当数据管道遇上元数据自动化在数据工程领域,手动维护Schema一直是ETL开发中最繁琐的环节之一。最近SeaTunnel与Gravitino的深度集成,通过RestAPI实现了元数据的自动化管理,这个看似简单的技术组合实际上解决了数据管道…

2026/9/10 23:44:42

H指数解析:学术影响力计算与应用指南

1. H指数:学术影响力的量化标尺作为一名长期跟踪学术评价指标的科研工作者,我经常需要向同行解释H指数的精妙之处。这个看似简单的数字背后,蕴含着对学者研究质量的立体化评估逻辑。2005年由物理学家Jorge Hirsch提出的H指数,如今…

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 0:00:55

目录对比去重实战:用哈希算法精准清理重复文件

我电脑里现在还有一块换了三次机的“数据墓地”硬盘,里面存着2016年以前所有旧笔记本的完整备份。平时不觉得有什么,直到前阵子想把它整理归档,发现同一个安装包、同一批照片、同一份论文草稿,在几个不同的备份目录里反复出现。更…

2026/9/10 0:00:55

Leaflet离线地图完整Demo合集:内网部署与坐标纠偏实战

简介:这是一份面向Web GIS开发者的LeafLet离线地图示例合集,帮助开发者快速掌握离线地图从搭建到交互的完整流程。压缩包共723个文件,大小14.06MB,以319个js脚本、175个html页面和29个css样式文件为主体,配合png/svg图…

2026/9/10 0:00:55

MATLAB读取Rinex 3.02观测文件:多系统GNSS数据解析实战

简介:基于MATLAB开发的Rinex3.02版观测文件(o文件)读取代码包,面向卫星定位导航方向的学习者与研究人员,用于解决新版观测文件的数据解析、历元提取与时间转换问题。压缩包共4个文件,包含两个m脚本、一个19…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码