> 技术文档 > 鸿蒙平台运行Lua脚本

鸿蒙平台运行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 文件,一共两个

// MakefileINSTALL_TOP?= /usr/local// src/MakefileCC?= gcc -std=gnu99RANLIB?= ranlib
  • 执行 make 进行编译

    export INSTALL_TOP=\"$(pwd)/$OUTPUT_DIR\"export CC=\"$TOOLCHAIN/bin/aarch64-unknown-linux-ohos-clang\"export RANLIB=\"$TOOLCHAIN/bin/llvm-ranlib\"make cleanmake generic -j8make install

    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(); 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与工程效能基础设施搭建。