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 示例。

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