FETCHCONTENT_SOURCE_DIR_GOOGLETEST 可经 GTEST_LOCAL_DIR 环境变量或 /tmp/deps/googletest-1.14.0 提供, 避免构建时强制访问 github
Lua Runner for Cangjie
v0.2.2版本更新:新增 typed interop(原始类型直通:Int64/Float64/Bool 与 Lua 直接互转,不经过字符串序列化),新增 callFunctionInt/Num/Bool、runScriptInt/Num/Bool、resultType API,扩展错误码 5016(结果类型不支持)。补充AI辅助编程标识。
🤖 AI 辅助编程标识
Important
本项目部分代码由 AI 辅助生成(包括但不限于:
loadFunction/callFunction/unloadFunction预加载函数能力、相关单元测试与文档)。 AI 生成代码均经过人工审查与实机验证(本仓库在本机以 Cangjie 1.1.0 实编译并通过功能运行验证),但请在使用前自行复核。
| 模块 | AI 辅助程度 | 说明 |
|---|---|---|
typed interop(callFunctionInt/Num/Bool、runScriptInt/Num/Bool、resultType 及 C 层 typed 函数) |
高(AI 主写,人工审查) | 原始类型直通映射:仓颉 Int64/Float64/Bool 与 Lua integer/number/boolean 直接互转,带类型标记的结果读取与严格校验(错误码 5016) |
loadFunction/callFunction/unloadFunction |
高(AI 主写,人工审查) | 预加载函数能力:加载文件→顶层执行一次→返回函数存入 Registry→可多次调用 |
| 单元测试(新增部分) | 中(AI 主写,人工修正) | 预加载与 typed interop 相关 GTest / 仓颉单测 |
| 文档(新增部分) | 低(AI 起草,人工定稿) | README / api.md 预加载与 typed interop 部分 |
Lua Runner for Cangjie 是一个专为仓颉语言设计的轻量级、高性能 Lua 脚本执行引擎。它通过 C FFI 桥接 C++,提供了稳定且易用的 Lua 虚拟机管理能力。 注:本项目是开发原生鸿蒙应用时产生的副产物,当前版本依然存在局限性与不足,请详细检查后再使用。。
除了基础的脚本嵌入功能外,该引擎的核心特色在于支持一种独特的 "栈式管道执行模式",能够实现脚本间的隐式参数传递,非常适合构建数据处理管道、游戏脚本系统或插件化架构。同时,它提供了完善的异常处理机制、灵活的 I/O 重定向功能,以及直接执行 Lua 代码片段的 doString 方法。
详细 API 文档请查看 doc/api.md。
特性
- 轻量级集成:基于 Lua 5.4,通过 FFI 直接与仓颉语言交互,性能损耗小。
- 原始类型直通:
Int64/Float64/Bool与 Luainteger/number/boolean直接互转,支持 typed 参数与结果(callFunctionInt/Num/Bool、runScriptInt/Num/Bool),整数可跨2^53保真,无需字符串往返。 - 栈式管道模式:支持脚本间基于栈的数据隐式传递,实现类似函数式管道的调用链。
- 预加载函数:提供
loadFunction/callFunction/unloadFunction,预加载一次 Lua 函数到内存(Registry),顶层代码仅执行一次,后续可多次调用,与管道模式互不干扰。 - doString:直接执行 Lua 代码字符串,无需写入文件。
- I/O 重定向:可自定义 Lua 标准输入/输出(
print,io.read)的回调函数,支持文件交换目录重定向。 - 模块化管理:提供
load和unload方法,支持按名称动态加载和卸载 Lua 脚本模块,避免全局污染。 - 完善的异常处理:定义了详细的错误码体系,通过
LuaError类统一抛出,便于调试和逻辑控制。 - 链式调用:大部分操作方法返回实例本身,支持流畅的调用风格。
快速开始
环境要求
- Cangjie 语言环境
基本用法
import luaRunner.*
main(): Int64 {
try {
// 1. 创建 Lua 运行实例
let runner = LuaRunner()
// 2. 执行 Lua 代码片段
let res = runner.doString("return 1 + 1")
println("Result: ${res}") // 输出: Result: 2
// 3. 加载并执行脚本
runner.load("./scripts/hello.lua", "myScript")
let result = runner.runScript("", "World")
println("Script result: ${result}")
} catch (e: LuaError) {
println("Lua Error [${e.code}]: ${e.getMessage()}")
}
return 0
}
当前局限性
- 数据类型限制:跨语言交互层从仅字符串扩展为原始类型直通(Int64/Float64/Bool 作为参数与返回值直接映射,不经过字符串序列化),复杂数据结构(表/嵌套)仍需序列化(如 JSON)。
- 容量限制:内部使用固定数组管理加载的库,上限为 20 个,超过将报错
5008。 - I/O 性能:I/O 重定向依赖于文件系统交换,相对于纯内存交互存在微小的性能开销。
第三方组件与合规说明
- 本项目仓库内包含 Lua 5.4.8 源码副本,用于构建底层原生运行时。
- Lua 5.4.8 使用 MIT License;其原始版权与许可声明可在
lib/lua/对应源码中查看。 - 本项目自身以
LGPL-3.0-or-later方式发布,使用或分发时请同时遵守项目本身以及所包含第三方组件的许可证要求。
许可证
本项目基于 LGPL-3.0-or-later 协议开源。仓库同时包含 Lua 5.4.8 的 MIT Licensed 源码副本,用于构建底层原生运行时。分发和集成时,请一并检查 LICENSE 以及 lib/lua/ 中随源码附带的许可声明。