如何將字符串從JavaScript傳入 Wasm/Rust

如何將字符串值從 JavaScript 傳入 Wasm/Rust

本文所用的所有資源都可以在 https://github.com/second-state/wasm-learning/tree/master/browser/hello 中找到

系列教程:

在前面的教程中,我們提到了 WebAssembly 應用程序通常由兩部分組成:

  • 運行在 WebAssembly 虛擬機內部的字節碼程序
  • 調用 WebAssembly 程序的主機應用程序

然而,輕量級的 WebAssembly 虛擬機只支持非常有限的數值數據類型。 另一方面,主機應用程序可能需要處理複雜的數據類型。 字符串就屬於這種複雜的數據類型。

字符串是複雜的,因為它包含大小未知和結構未知的數據(即編碼)。 主機應用程序不能直接在 WebAssembly 之間傳遞字符串數據。 它必須將字符串值與數值和數組相互轉換。

《WebAssembly 中的字符串》會讓你對字符串有更深的瞭解

如何將字符串從JavaScript傳入 Wasm/Rust | WebAssembly入門教程

這個教程將展示如何構建一個真正的“ hello world” 以及如何在 WebAssembly 中處理字符串。

  • 主機應用程序是用 JavaScript 編寫的,在 Web 瀏覽器中運行。 它在 WebAssembly 函數調用之間傳遞字符串。
  • WebAssembly 字節碼程序是用 Rust 編寫的。 它以 Rust String 結構的形式接收和返回字符串。

教程的源代碼在這裡。

設置

我們在這個示例中介紹的重要開發工具是 wasm-pack。 它將 Rust 源代碼編譯成一個 WebAssembly 字節碼程序,然後生成一個 JavaScript 模塊,該模塊可以與 WebAssembly 程序交互。 生成的代碼負責輸入/輸出數據的編碼和管理, 這使得 JavaScript 開發者更容易調用 WebAssembly 函數。

按照下面的步驟安裝 Rust 和 wasm-pack工具。

<code># 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
/<code>
<code># Install wasm-pack tools

$ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
/<code>

Rust 寫的 WebAssembly 程序

在這個示例中,Rust 程序在“ hello”後面追加輸入字符串。 讓我們創建一個新的 cargo項目。 由於這個程序是從主機應用程序調用的,而不是作為獨立的可執行文件運行,因此我們將創建一個 hello 項目。

<code>$ cargo new --lib hello
$ cd hello
/<code>

編輯 Cargo.toml 文件,添加一個[lib] 部分。 它會告訴編譯器在哪裡可以找到庫的源代碼,以及如何生成字節碼輸出。 這裡我們還需要一個 wasm-bindgen 的依賴項。是實用的wasm-pack 為 Rust WebAssembly 程序生成 JavaScript 綁定。

<code>[lib]
name = "hello_lib"
path = "src/lib.rs"
crate-type =["cdylib"]
[dependencies]
wasm-bindgen = "0.2.50"
/<code>

下面是Rust 程序 src/lib.rs的內容。實際上,我們可以在這個庫文件中定義多個外部函數,並且所有這些函數都可以通過 WebAssembly 在主機 JavaScript 應用程序中使用。 #[wasm_bindgen] 標籤指示構建工具在 Rust / WebAssembly 和 JavaScript 模塊中生成通信接口。

<code>use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn say(s: String) -> String {
let r = String::from("hello ");
return r + &s;
}

/<code>

接下來,將 Rust 源代碼編譯成 WebAssembly 字節碼,並生成相應的 JavaScript 模塊。

<code>$ wasm-pack build --target web
/<code>

結果是下面兩個de 文件。.wasm文件是 WebAssembly 字節碼程序,.js 文件是JavaScript模塊。

<code>pkg/hello_lib_bg.wasm
pkg/hello_lib.js
/<code>

JavaScript主機

讓我們回到 JavaScript 主機應用。有了生成的 hello_lib.js 模塊,可以非常容易地寫 JavaScript 來調用 WebAssembly 函數。在 import 之後, WebAssembly say() 函數現在成了一個同名的JavaScript 函數。完整的網頁源文件在這裡。

<code>/<code>

hello_lib_bg.wasm 程序是由hello_lib.js 模塊加載, 將HTML 文件 hello_lib.js 和 hello_lib_bg.wasm 文件放在網絡服務器上,現在得到了一個在輸入任何名稱都能 "say hello" 的網頁了。

下一步是什麼呢?

到目前為止,我們已經瞭解瞭如何從託管在瀏覽器中的 JavaScript 訪問 WebAssembly 程序。 但更重要的是,我們相信 WebAssembly 真正的潛力在於服務器端。 在下一個教程中,我們將關注服務器端的 WebAssembly 示例!


分享到:


相關文章: