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與工程效能基礎設施搭建。
?