如何将字符串值从 JavaScript 传入 Wasm/Rust
本文所用的所有资源都可以在 https://github.com/second-state/wasm-learning/tree/master/browser/hello 中找到
系列教程:
在前面的教程中,我们提到了 WebAssembly 应用程序通常由两部分组成:
然而,轻量级的 WebAssembly 虚拟机只支持非常有限的数值数据类型。 另一方面,主机应用程序可能需要处理复杂的数据类型。 字符串就属于这种复杂的数据类型。
字符串是复杂的,因为它包含大小未知和结构未知的数据(即编码)。 主机应用程序不能直接在 WebAssembly 之间传递字符串数据。 它必须将字符串值与数值和数组相互转换。
《WebAssembly 中的字符串》会让你对字符串有更深的了解
这个教程将展示如何构建一个真正的“ hello world” 以及如何在 WebAssembly 中处理字符串。
主机应用程序是用 JavaScript 编写的,在 Web 浏览器中运行。 它在 WebAssembly 函数调用之间传递字符串。
WebAssembly 字节码程序是用 Rust 编写的。 它以 Rust String 结构的形式接收和返回字符串。
教程的源代码在这里。
我们在这个示例中介绍的重要开发工具是 wasm-pack
。 它将 Rust 源代码编译成一个 WebAssembly 字节码程序,然后生成一个 JavaScript 模块,该模块可以与 WebAssembly 程序交互。 生成的代码负责输入/输出数据的编码和管理, 这使得 JavaScript 开发者更容易调用 WebAssembly 函数。
按照下面的步骤安装 Rust 和 wasm-pack
工具。
# Install Rust
$ sudo apt-get update
$ sudo apt-get -y upgrade
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env
# Install wasm-pack tools
$ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
在这个示例中,Rust 程序在“ hello”后面追加输入字符串。 让我们创建一个新的 cargo
项目。 由于这个程序是从主机应用程序调用的,而不是作为独立的可执行文件运行,因此我们将创建一个 hello
项目。
$ cargo new --lib hello
$ cd hello
编辑 Cargo.toml
文件,添加一个[lib]
部分。 它会告诉编译器在哪里可以找到库的源代码,以及如何生成字节码输出。 这里我们还需要一个 wasm-bindgen
的依赖项。是实用的wasm-pack
为 Rust WebAssembly 程序生成 JavaScript 绑定。
[lib]
name = "hello_lib"
path = "src/lib.rs"
crate-type =["cdylib"]
[dependencies]
wasm-bindgen = "0.2.50"
下面是Rust 程序 src/lib.rs
的内容。实际上,我们可以在这个库文件中定义多个外部函数,并且所有这些函数都可以通过 WebAssembly 在主机 JavaScript 应用程序中使用。 #[wasm_bindgen]
标签指示构建工具在 Rust / WebAssembly 和 JavaScript 模块中生成通信接口。
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn say(s: String) -> String {
let r = String::from("hello ");
return r + &s;
}
接下来,将 Rust 源代码编译成 WebAssembly 字节码,并生成相应的 JavaScript 模块。
$ wasm-pack build --target web
结果是下面两个de 文件。.wasm
文件是 WebAssembly 字节码程序,.js
文件是JavaScript模块。
pkg/hello_lib_bg.wasm
pkg/hello_lib.js
让我们回到 JavaScript 主机应用。有了生成的 hello_lib.js
模块,可以非常容易地写 JavaScript 来调用 WebAssembly 函数。在 import
之后, WebAssembly say()
函数现在成了一个同名的JavaScript 函数。完整的网页源文件在这里。
hello_lib_bg.wasm
程序是由hello_lib.js
模块加载, 将HTML 文件 hello_lib.js
和 hello_lib_bg.wasm
文件放在网络服务器上,现在得到了一个在输入任何名称都能 “say hello” 的网页了。
到目前为止,我们已经了解了如何从托管在浏览器中的 JavaScript 访问 WebAssembly 程序。 但更重要的是,我们相信 WebAssembly 真正的潜力在于服务器端。 在下一个教程中,我们将关注服务器端的 WebAssembly 示例!