鸿蒙平台运行Lua脚本
1. 目标
使用 rust 在移动端实现 Lua 脚本的运行。
2. 核心步骤
[Rust Host App]│├── [mLua VM] (通过 `mlua` 或 `rlua` 库嵌入)│ ├── 独立Lua状态(隔离执行)│ ├── 受限标准库(禁用危险函数)│ └── 内存/CPU限制│└── [Rust ↔ Lua 互操作]├── 导出Rust函数/结构体到Lua└── 从Lua回调Rust
1. Android 和 iOS
-
mlua 对 这两端的实配较为成熟,rust 可自动识别交叉编译工具链
-
只需在 features 中打开
vendored
配置即可
# Cargo.toml
[dependencies]
mlua = {version = "0.10.5", features = ["lua54", "vendored"]}
2. Harmony
-
下载 Lua 源代码,本次使用的版本是 5.4.7
-
修改 Makefile 文件,一共两个
// Makefile
INSTALL_TOP?= /usr/local// src/Makefile
CC?= gcc -std=gnu99
RANLIB?= ranlib
-
执行 make 进行编译
export INSTALL_TOP="$(pwd)/$OUTPUT_DIR"
export CC="$TOOLCHAIN/bin/aarch64-unknown-linux-ohos-clang"
export RANLIB="$TOOLCHAIN/bin/llvm-ranlib"make clean
make generic -j8
make install
-
经过上述步骤会生成鸿蒙平台的 .a 库
3. 配置rust工程
-
引入 mlua,和安卓、iOS 不同,这里 features 要选择
module
mlua = { version = "0.10.5", features = ["lua54", "module"] }
-
把 .a 文件 copy 到 libs 目录下,并编辑 build.rs
"aarch64-unknown-linux-ohos" => {println!("cargo:rustc-link-search=native=./libs/ohos/arm64-v8a");println!("cargo:rustc-link-lib=static=lua");napi_build_ohos::setup(); }
-
编写 napi 方法
#[napi]
fn napi_pi(path: String) -> i64 {init_logger();hook_panic(Some(Box::new(PanicListener)));calculate_pi(path) as i64
}fn calculate_pi(path:String) -> u128 {let start = Instant::now();let script = std::fs::read_to_string(path + "/lua_scripts/pi.lua").expect("Failed to read pi.lua");let lua = Lua::new();// 加载Lua脚本lua.load(&script).exec().expect("Failed to load pi.lua");let test_pi: mlua::Function = lua.globals().get("testPi").expect("Failed to get testPi");let result:bool = test_pi.call((100)).expect("Failed to call pi.lua");start.elapsed().as_millis()
}
4. 配置鸿蒙工程
-
把 lua 脚本 copy 到 raw 文件夹中,然后 copy 到沙盒目录
async copyRawFiles(node: string) {const resManager = getContext().resourceManager;const baseDir = `${getContext().getApplicationContext().filesDir}`;const queue = new Queue<string>();queue.add(node);while (queue.length > 0) {const currentNode = queue.pop();try {const bytes = resManager.getRawFileContentSync(currentNode);hilog.info(DOMAIN, 'testTag', `${bytes.length}`);const targetPath = `${baseDir}/${currentNode}`const fileStream = fs.createStreamSync(targetPath, "w+");fileStream.writeSync(bytes.buffer);fileStream.close();} catch (e) {hilog.info(DOMAIN, 'testTag', `${JSON.stringify(e)}`);const targetPath = `${baseDir}/${currentNode}`if (!fs.accessSync(targetPath)) {fs.mkdirSync(targetPath);}const fileList = resManager.getRawFileListSync(currentNode);fileList.forEach((it) => queue.add(`${currentNode}/${it}`));}}
}
-
调用 rust napi 方法
import rust from 'liblogic_device_test.so';async executeLuaPi() {const baseDir = `${getContext().getApplicationContext().filesDir}`;let total = 0;for (let i = 0; i < 100; i++) {const time: number = rust.napiPi(`${baseDir}/lua`);total += time;}hilog.info(DOMAIN, 'testTag', `${total}`); }
3. 团队介绍
「三翼鸟数字化技术平台-智家APP平台」通过持续迭代演进移动端一站式接入平台为三翼鸟APP、智家APP等多个APP提供基础运行框架、系统通用能力API、日志、网络访问、页面路由、动态化框架、UI组件库等移动端开发通用基础设施;通过Z·ONE平台为三翼鸟子领域提供项目管理和技术实践支撑能力,完成从代码托管、CI/CD系统、业务发布、线上实时监控等Devops与工程效能基础设施搭建。