< 返回版块

planet0104 发表于 2020-03-24 15:11

Tags:Webassembly,微信小程序

wasm-bindgen 提供 WebAssembly(wasm) 模块和 JavaScript 之间的高级别交互,我们可以用它来访问微信小程序的API。

首先在Cargo.toml中引入依赖的库(js-sys是wasm-bindgen中的JS原始API绑定库):

[package]
name = "hello"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2.59"
js-sys = "0.3.36"

[profile.release]
lto = true
opt-level = 'z'
codegen-units = 1
panic = 'abort'

然后添加Rust代码:

use js_sys::*;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
    #[wasm_bindgen(js_namespace = console)]
    fn error(s: &str);
    #[wasm_bindgen(js_namespace = wx)]
    fn showModal(param: &Object);
}

fn page_on_load() -> Result<JsValue, JsValue> {
    let param = Object::new();
    Reflect::set(&param, &JsValue::from("title"), &JsValue::from("提示"))?;
    Reflect::set(
        &param,
        &JsValue::from("content"),
        &JsValue::from("这是一个模态弹窗"),
    )?;
    showModal(&param);
    Ok(JsValue::TRUE)
}

#[wasm_bindgen(js_name = onLoad)]
pub fn on_load() {
    match page_on_load() {
        Err(err) => error(&format!("{:?}", err)),
        _ => (),
    };
}

#[wasm_bindgen(start)]
pub fn run() {
    log("start");
}

其中,extern "C" {} 中是导入的js函数,包括:

console.log()
console.error()
wx.showModal()

另外导出了两个Rust函数onLoad和run,可以通过模块访问。

在page_on_load中,使用Reflect来创建showModal的参数,如果方法中出现异常错误,会在console.error()中打印日志。

最后编译它:

:: Compile our wasm module and run `wasm-bindgen`
wasm-pack build --target web

:: Run the `wasm2js` tool from `binaryen`
wasm2js pkg/hello_bg.wasm -o pkg/hello_bg.js

node pack.js

copy pkg\_hello.js wasm-bindgen-test\pages\index\hello.js

pack.js是预处理脚本,对hello_bg.js和hello.js做了一些修改,使之可以在小程序中正常运行。

微信小程序目前仍然不支持Webassembly,需要调用wasm2js将wasm转换成js文件,wasm2js.exe是emsdk里的工具,参考这里安装: https://emscripten.org/docs/getting_started/downloads.html​ emscripten.org

下面看小程序的代码,在index中引入hello.js(run是启动函数可以不调用):

//index.js
const app = getApp()

var hello = require("hello");

hello.run();

Page({
  onLoad: function () {
    hello.onLoad();
  }
})

再写一个导出md5函数的例子:

[dependencies]
md5 = "0.7.0"
#[wasm_bindgen]
pub fn md5(data: JsValue) -> JsValue {
    let data: String = JsString::from(data).into();
    let digest = md5::compute(data.as_bytes());
    let hex: JsString = JsString::from(format!("{:x}", digest).as_str());
    JsValue::from(JsString::from(hex))
}

调用它:


//index.js
var hello = require("hello");

var hex = hello.md5("Rust编程语言");

console.log("MD5=", hex);

输出:

MD5= 8f17b679c7fb8e4b55df1f2e39108bd5

源码地址: https://github.com/planet0104/wx-wasm-bindgen

原文地址: https://zhuanlan.zhihu.com/p/115828639


Ext Link: https://zhuanlan.zhihu.com/p/115828639

评论区

写评论

还没有评论

1 共 0 条评论, 1 页