ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

jynew 项目中的 xLua 通用字节码(Compatible Bytecode):跨平台 Lua 字节码编译与加载实战

jynew 项目中的 xLua 通用字节码(Compatible Bytecode):跨平台 Lua 字节码编译与加载实战 jynew 项目中的 xLua 通用字节码Compatible Bytecode跨平台 Lua 字节码编译与加载实战【免费下载链接】jynewJinYongLegend-like RPG Game Framework with full Modding support and 10 hours playable samples of game.项目地址: https://gitcode.com/GitHub_Trending/jy/jynewxLua 的官方 Lua 字节码存在 32 位与 64 位不互通的历史缺陷导致同一份luac产物无法在多个目标平台通用。本文以 xLua 官方文档《通用字节码》compatible_bytecode.md为核心骨架结合 jynew 仓库中实际收录的 xLua 源码与加载器示例完整讲解通用字节码格式的编译开关、配套luac工具链、CustomLoader 二进制加载链路以及基于 OpCode 二次定制的专用字节码方案读完即可在自有项目含 jynew 这类以 xLua 承载 Lua 逻辑的 Unity 项目中落地一套跨平台、可保护源码的 Lua 字节码发布流程。背景官方 Lua 字节码的 32/64 位壁垒很多项目希望通过luac将 Lua 源码预编译为字节码后再加载以达到加载提速与源码保护的双重目的。但官方 Lua 有一个先天缺陷字节码是分 32 位和 64 位版本的。换句话说32 位 Lua 环境只能运行 32 位luac编译出的产物64 位环境也只能运行 64 位产物。对于需要同时发布 Android32/64 位、iOS、Windows、macOS 等多个目标平台的 Unity 项目而言这意味着要为每个架构分别维护一份编译产物发布与校验链路都变得复杂。针对这一问题xLua 对 Lua 源码做了少量改造通过一个编译开关即可让 xLua 的宿主库与配套的luac同时生成/识别一种跨平台通用格式的字节码从而做到编译一份处处运行。方案原理-DLUAC_COMPATIBLE_FORMAT编译开关xLua 的通用字节码能力并非运行时黑魔法而是从编译期介入在编译 xLua 原生 Plugins各平台的xlua.dll/.so/.a等时通过 CMake 传入-DLUAC_COMPATIBLE_FORMATON使 xLua 内置的 Lua 虚拟机当前文档对应 lua-5.3.5在加载字节码时使用通用格式配套地用同一开关编译出的luac工具产出的字节码才会被上述 Plugins 正确识别。也就是说通用字节码 特制 Plugins 特制 luac 的成对使用二者缺一不可。原文档明确给出了两个前提警告详见 compatible_bytecode.md一旦做了本文所述改动你的 xLua将无法再加载官方luac编译的字节码——通用格式与官方格式不兼容属于互斥选择截至 2018/9/14该改法已知在一个上线一个多月的项目正常运行但不代表此改法在任何情况下都没问题引入前建议充分自测尤其是跨平台回归。操作指南三步完成通用字节码落地第一步用兼容格式开关重新编译 xLua Plugins修改各平台的编译脚本在cmake命令中追加-DLUAC_COMPATIBLE_FORMATON。以make_win64_lua53.bat为例修改后的脚本如下完整保留原文档脚本mkdir build64 pushd build64 cmake -DLUAC_COMPATIBLE_FORMATON -G Visual Studio 14 2015 Win64 .. popd cmake --build build64 --config Release md plugin_lua53\Plugins\x86_64 copy /Y build64\Release\xlua.dll plugin_lua53\Plugins\x86_64\xlua.dll pause用修改后的编译脚本重新编译各平台的 xLua 库并覆盖原 Plugins 目录下对应文件即完成宿主侧改造。关于各平台编译环境xLua 的 FAQ 给出了约束见 faq.md可对照排查源码编译依赖CMake安装后执行make_xxxx_yyyy.zz即可其中xxxx代表平台如 ios、androidyyyy是要集成的虚拟机有lua53和luajit两种zz是后缀Windows 下为.bat其它平台为.shWindows 编译依赖Visual Studio 2015对应上例-G Visual Studio 14 2015 Win64生成器Android 编译需在 Linux 下执行依赖NDK且需要把脚本中的ANDROID_NDK指向 NDK 安装目录iOS 与 OS X 需要在 macOS 下编译。脚本体系的具体命名可参考 XLua增加删除第三方lua库.md 的说明例如 Windows 64 位 Lua 5.3 版本为make_win64_lua53.batAndroid 的 LuaJIT 版本为make_android_luajit.sh编译脚本执行完毕后会自动把产物拷贝到plugin_lua53或plugin_luajit目录。关于仓库路径的说明原文档此处链接指向的build/luac/目录属于 xLua 源码工程xLua_Project_Root/build下的构建脚本目录本仓库jynew只收录了运行期使用的 Assets/XLua 部分未收录该 CMake 构建工程若需编译原生库请基于 xLua 官方完整工程中的build目录操作。本仓库 Plugins 下的预编译产物位于 jyx2/Assets/Plugins含 Android、iOS、WebGL、WSA、x86/x86_64 等子目录。第二步编译能生成兼容格式的 luac通用字节码需要配套的工具链到 xLua 工程的build/luac/目录下Windows 平台执行make_win64.batmacOS / Linux 平台执行make_unix.sh。编译出的这个luac只会产出通用格式字节码后续必须只使用这个特定的 luac 第一步编译的 Plugins 配套使用不能与官方 luac 或官方插件混搭。第三步通过 CustomLoader 以二进制方式加载字节码字节码加载通过 xLua 的CustomLoader机制完成。在 jynew 仓库中该机制的完整定义位于 LuaEnv.cspublic delegate byte[] CustomLoader(ref string filepath); internal ListCustomLoader customLoaders new ListCustomLoader(); // loader : CustomLoader filepath参数ref类型输入是require的参数如果需要支持调试需要输出真实路径。 // 返回值如果返回null代表加载该源下无合适的文件否则返回UTF8编码的byte[] public void AddLoader(CustomLoader loader) { customLoaders.Add(loader); }核心语义与教程文档XLua教程.md一致require实际是按顺序调用注册的 loader有一个成功即停止全部失败则报文件找不到loader 回调的入参是require透传的模块名回调内据此去加载指定文件如需支持调试应将filepath修改为真实路径传出回调返回byte[]返回null表示该 loader 找不到对应文件否则返回文件内容字节码场景下即luac产物。一个最小可运行的自定义加载器示例见仓库教程 CustomLoader.cs其中用luaenv.AddLoader(...)注册回调、用luaenv.DoString(require InMemory)触发加载并在Update中驱动luaenv.Tick()、在OnDestroy中Dispose这些生命周期管理对字节码加载同样适用。这一步最容易犯的错误用某种文本 Encoding如Encoding.UTF8.GetBytes去加载二进制文件。字节码是二进制格式任何文本编码转换都会破坏luac文件格式导致加载失败或运行时异常。务必以二进制方式读取文件后原样返回byte[]——这正是文档中特别强调的注意点。如果业务上需要更强的安全性可以进一步参考仓库中的签名加载器示例 SignatureLoaderTest.cs它在AddLoader中套了一层签名校验公钥验签非常契合字节码是下载回来的 / 需要防篡改的发布场景——先验签、后交给虚拟机加载。进阶PS 专题——OpCode 修改与专用字节码原文档的 PS 部分指出如果项目想要完全私有的专用格式字节码进一步防止被通用反编译器解析可以直接在 Lua 源码目前对应 lua-5.3.5上修改 OpCode 定义后重新执行上述第一步重编 Plugins和第二步重编 luac即可让整个工具链切换到私有格式。这一思路与通用字节码完全一致修改发生在虚拟机与编译器共享的字节码定义层宿主与工具链同步重编即保持成对兼容。从实现上讲通用格式本质上是改了字节码格式的 lua-5.3.5而 OpCode 定制则是把这种修改推向极致——只要保证特制 luac 产出 → 特制 Plugins 加载的配对关系任何格式层面的定制都是可行的。文档与源码结构可以支持这一推断具体 OpCode 改动方案需基于实际 Lua 源码自行设计。在 jynew 项目中的落地视角jynew 是一个以 Unity 承载、Lua 驱动玩法逻辑的金庸群侠传类 RPG 框架xLua 是其 Lua 运行时基础设施见 Assets/XLua工程内的 Lua 脚本分布在 Assets/LuaScripts含InitLuaScripts.lua初始化入口、Jyx2Battle战斗脚本、Jyx2Configs配置脚本等以及 Assets/ModsJYX2 / SAMPLE / xiastart_roguelike 等模组各自携带大量.lua文件中。当需要以字节码形式发布这些脚本时按本文第一步重编目标平台 Plugins覆盖 jyx2/Assets/Plugins 下的预编译库用配套 luac 将.lua预编译为通用字节码产物可按平台架构统一使用一份通过LuaEnv.AddLoader注册一个以二进制方式读取字节码文件的加载器在 LuaEnv.cs 的 loader 链中返回产物内容再以require触发加载。这样即可在一个入口如InitLuaScripts.lua或模组加载器下统一管理字节码的分发与加载同时规避官方字节码 32/64 位不互通带来的多产物维护成本。小结通用字节码的本质通过在 CMake 编译期传入-DLUAC_COMPATIBLE_FORMATON让 xLua 宿主库与配套 luac 同时切换到跨平台兼容的字节码格式三条铁律特制 Plugins 与特制 luac 必须成对使用改造后不再兼容官方 luac 字节码字节码必须二进制加载、禁用任何文本 Encoding 转换可扩展性在 lua-5.3.5 源码上修改 OpCode 后重走重编 Plugins 重编 luac两步即可获得完全私有的专用字节码格式仓库佐证compatible_bytecode.md方案文档、LuaEnv.csCustomLoader 机制实现、CustomLoader.cs加载器最小示例、SignatureLoaderTest.cs验签加载进阶示例、faq.md各平台编译环境要求。【免费下载链接】jynewJinYongLegend-like RPG Game Framework with full Modding support and 10 hours playable samples of game.项目地址: https://gitcode.com/GitHub_Trending/jy/jynew创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表