1. 目标
使用 rust 在移动端实现 Lua 脚本的运行。
2. 核心步骤
less
[Rust Host App]
│
├── [mLua VM] (通过 `mlua` 或 `rlua` 库嵌入)
│ ├── 独立Lua状态(隔离执行)
│ ├── 受限标准库(禁用危险函数)
│ └── 内存/CPU限制
│
└── [Rust ↔ Lua 互操作]
├── 导出Rust函数/结构体到Lua
└── 从Lua回调Rust
- Android 和 iOS
- mlua 对 这两端的实配较为成熟,rust 可自动识别交叉编译工具链
- 只需在 features 中打开
vendored
配置即可
ini
# Cargo.toml
[dependencies]
mlua = {version = "0.10.5", features = ["lua54", "vendored"]}
- Harmony
- 下载 Lua 源代码,本次使用的版本是 5.4.7
- 修改 Makefile 文件,一共两个
javascript
// Makefile
INSTALL_TOP?= /usr/local
// src/Makefile
CC?= gcc -std=gnu99
RANLIB?= ranlib
- 执行 make 进行编译
bash
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 库
- 配置rust工程
- 引入 mlua,和安卓、iOS 不同,这里 features 要选择
module
ini
mlua = { version = "0.10.5", features = ["lua54", "module"] }
-
把 .a 文件 copy 到 libs 目录下,并编辑 build.rs
arduino"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 方法
rust
#[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()
}
- 配置鸿蒙工程
- 把 lua 脚本 copy 到 raw 文件夹中,然后 copy 到沙盒目录
ini
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 方法
typescriptimport 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与工程效能基础设施搭建。