鸿蒙平台运行Lua脚本

发布于:2025-07-25 ⋅ 阅读:(14) ⋅ 点赞:(0)

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

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


      网站公告

      今日签到

      点亮在社区的每一天
      去签到