5分钟实现一个简单的 WebAssembly 应用|WebAssembly 入门教程

在 Rust 中创建一个简单的 WebAssembly 应用程序,然后从 JavaScript 调用这个程序

本文所涉及的所有代码可以在 https://github.com/second-state/wasm-learning/tree/master/browser/triple 中找到。

WebAssembly 入门教程
系列教程

  1. WebAssembly 快问快答
  2. Rust 的 Hello world

在本教程中,我们将创建一个非常简单但很完整的 WebAssembly 应用程序。

Webassembly 应用程序通常由两部分组成。

  • 运行在 WebAssembly 虚拟机内部以执行计算任务的字节码程序

  • 提供 UI、networking、数据库,以及调用 WebAssembly 程序以执行关键计算任务或业务逻辑的主机应用程序

在本教程中,主机应用程序是用 JavaScript 编写的,并在 web 浏览器中运行。 Webassembly 字节码程序是用 Rust 编写的。

现在,先让我们看看 Rust 程序是如何编写的。

在 Rust 中的 WebAssembly 程序

在这个例子中,Rust 程序将输入数字简单地增加了三倍并返回结果。 首先将 WebAssembly 工具安装到 Rust 编译器。

# 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 WebAssembly tools

$ rustup target add wasm32-wasi
$ rustup override set nightly
$ rustup target add wasm32-wasi --toolchain nightly

接下来,创建一个新的 cargo 项目。
由于这个程序是从主机应用程序调用的,而不是作为独立的可执行文件运行,因此我们将创建一个 lib 项目。

$ cargo new --lib triple
$ cd triple

编辑 Cargo.toml 文件以添加[lib]节。 它会告诉编译器在哪里可以找到库的源代码,以及如何生成字节码输出。

[lib]
name = "triple_lib"
path = "src/lib.rs"
crate-type =["cdylib"]

下面是 Rust 程序 src/lib.rs 的内容. 实际上,你可以在这个库文件中定义多个外部函数,并且所有这些函数都可以通过 WebAssembly 在 JaveScript 主机上使用。

#[no_mangle]
pub extern fn triple(x: i32) -> i32 {
  return 3 * x;
}

接下来你可以用下面的命令行编译 Rust 的源代码到WebAssembly的字节码中。

$ cargo +nightly build --target wasm32-wasi --release

WebAssembly 字节码文件是 target/wasm32-wasi/release/triple_lib.wasm

JavaScript 主机

我们使用 JavaScript 加载 WebAssembly 字节码程序并调用它的函数。 由于大多数浏览器已经支持 WebAssembly, JavaScript 实际上可以作为一个网页运行。

无须赘述,下面是 JavaScript 模块的相关部分,用于加载、导出和调用 WebAssembly 函数。 完整的网页源文件在这里

<script>
  if (!('WebAssembly' in window)) {
    alert('you need a browser with wasm support enabled :(');
  }
  (async () => {
      const response = await fetch('triple_lib.wasm');
      const buffer = await response.arrayBuffer();
      const module = await WebAssembly.compile(buffer);
      const instance = await WebAssembly.instantiate(module);
      const exports = instance.exports;
      const triple = exports.triple;
      
      var buttonOne = document.getElementById('buttonOne');
      buttonOne.value = 'Triple the number';
      buttonOne.addEventListener('click', function() {
        var input = $("#numberInput").val();
        alert(input + ' tripled equals ' + triple(input));
      }, false);
  })();
</script>

可以看到 JavaScript 代码加载了 WebAssembly 虚拟机的 triple_lib.wasm 文件, 导出其外部函数,然后根据需要调用这些函数。

将这个 HTML 文件和 triple_lib.wasm 文件放在web 服务器上,你就可以访问网页,在网页上输入的任何数字会自动乘以三。

那么字符串呢

现在你注意到了,这个例子并不是一个 hello world。 WebAssembly函数计算数字,但不会像 hello world 那样操作字符串。

这是为什么呢? 我们将在下一个教程中回答这个问题,并给出一个真实的 hello world 示例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章