[WASM] Set up wasm-bindgen for easy Rust/JavaScript Interoperability

Interoperability between JavaScript and Rust is limited to numerics and accessing memory directly. Since this can be exhausting and overwhelming to do manually the Rust/Wasm team has created the wasm-bindgen project to facilitate high-level interactions between Rust and JavaScript.

 

WebAssembly programs operate on a limited set of value types. Due to this, the functions bridging between JavaScript and Rust only allow for primitive numeric types, like integer or float. 

So if you pass a string between Javascript and WASM, it convert to a number.

 

This is not what we wanted to achieve here. Fortunately, we can work around this by directly reading or writing to WebAssembly's memory using JavaScript. Each WASM module has a linear memory, which is initialized during instantiation.

 

While sometimes accessing memory directly can be useful, in most cases, it's quite cumbersome. That's why the generic bindgen-style framework, wasm-bindgen, was created. The framework makes it possible to write idiomatic Rust function signatures that map to idiomatic JavaScript functions automatically.

 

To get started, we add wasm-bindgen as a dependency to our Cargo configuration.

# Cargo.toml

[package]
name = "utils"
version = "0.1.0"
authors = ["zhentian-wan <answer881215@gmail.com>"]
edition = "2018"

[dependencies]
wasm-bindgen="0.2"

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

 

lib.rs:

#![feature(use_extern_macros)]

extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[wasm_bindgen(module = "../domUtils")]
extern {
  fn appendStringToBody(s: &str);
}

#[wasm_bindgen]
pub extern fn run() {
  appendStringToBody("Hello World");
}

 

We compile our Rust library using wasm-pack build

wasm-pack build

This way, we can pass types, like strings, into our Rust code without manually having to take care of the conversion.

 

domUtils.js:

export const appendStringtoBody = (value) => {
  const text = document.createTextNode(value);
  document.body.appendChild(text);
}

When using wasm-bindgen, we then can declare that the module should be imported.

 

Run:

wasm-pack build

npx webpack-dev-server

 

posted @ 2018-10-23 03:34  Zhentiw  阅读(467)  评论(0编辑  收藏  举报