如何将字符串值从 JavaScript 传入 Wasm/Rust本文所用的所有资源都可以在 https://github.com/second-sta... 中找到
系列教程:
在前面的教程中,我们提到了 WebAssembly 应用程序通常由两部分组成:
- 运行在 WebAssembly 虚拟机内部的字节码程序
- 调用 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 写的 WebAssembly 程序
在这个示例中,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主机
让我们回到 JavaScript 主机应用。有了生成的 hello_lib.js
模块,可以非常容易地写 JavaScript 来调用 WebAssembly 函数。在 import
之后, WebAssembly say()
函数现在成了一个同名的JavaScript 函数。完整的网页源文件在这里。
<script type="module">
import init, { say } from './hello_lib.js';
async function run() {
await init();
var buttonOne = document.getElementById('buttonOne');
buttonOne.addEventListener('click', function() {
var input = $("#nameInput").val();
alert(say(input));
}, false);
}
run();
</script>
hello_lib_bg.wasm
程序是由hello_lib.js
模块加载, 将HTML 文件 hello_lib.js
和 hello_lib_bg.wasm
文件放在网络服务器上,现在得到了一个在输入任何名称都能 "say hello" 的网页了。
下一步是什么呢?
到目前为止,我们已经了解了如何从托管在浏览器中的 JavaScript 访问 WebAssembly 程序。 但更重要的是,我们相信 WebAssembly 真正的潜力在于服务器端。 在下一个教程中,我们将关注服务器端的 WebAssembly 示例!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。