WebAssembly 基礎
詳情參考《WebAssembly | MDN》
(1)概述
- WebAssembly 簡稱 WASM 或 WA,是一種新的編碼方式,可以在現(xiàn)代的 Web 瀏覽器中運行
- 可以通過編譯器,把多種編程語言(如 C/C++、C#、Go、Python、Rust、TypeScript 等)編寫的代碼轉(zhuǎn)化為 WA,并在瀏覽器中使用
- 特點:
- 靈活度高:是一種低級的類匯編語言
- 體積較?。壕哂芯o湊的二進制格式
- 性能提升:接近原生的性能運行
- WA 可以與 JavaScript 共存,允許兩者一起工作
- WA 關鍵概念:
- 模塊:表示一個已經(jīng)被瀏覽器編譯為可執(zhí)行機器碼的 WA 二進制代碼
- 內(nèi)存:一個可變長的
ArrayBuffer
- 表格:一個可變長的類型化數(shù)組
- 實例:一個模塊及其在運行時使用的所有狀態(tài)(包括內(nèi)存、表格和一系列導入值)
- 使用 WA 編寫的相關應用:Figma 等
(2)加載與運行
通常,編譯器將其他語言的代碼編譯成 .wasm 文件,以便在 WA 環(huán)境中使用
在瀏覽器環(huán)境中,可以通過 AJAX 導入外部文件,如導入 .wasm 文件
JavaScript 中的 WebAssembly
對象是所有 WA 相關功能的命名空間,其中 WebAssembly.compile
/ WebAssembly.instantiate
或 WebAssembly.compileStreaming
/ WebAssembly.instantiateStreaming
方法組合可以用于加載和運行 WA 代碼
| fetch("main.wasm") |
| .then((response) => response.arrayBuffer()) |
| .then((bytes) => WebAssembly.compile(bytes)) |
| .then((module) => { |
| const instance = new WebAssembly.Instance(module); |
| console.log(instance.exports); |
| }); |
或
| WebAssembly.instantiateStreaming(fetch("main.wasm")).then( |
| (results) => { |
| const instance = results.instance; |
| console.log(instance.exports); |
| }, |
| ); |
(3)相關 JavaScript API
WebAssembly
:所有 WA 相關功能的命名空間
a. 對象
WebAssembly.Module
:包含已經(jīng)由瀏覽器編譯的無狀態(tài) WebAssembly 代碼WebAssembly.Global
:一個全局變量實例,可以被 JavaScript 和 importable/exportable 訪問WebAssembly.Instance
:有狀態(tài),是 WebAssembly.Module
的一個可執(zhí)行實例WebAssembly.Table
:代表 WA 表格概念的 JavaScript 包裝對象,具有類數(shù)組結(jié)構(gòu),存儲了多個函數(shù)引用WebAssembly.Tag
:定義了一種 WA 異常的類型,該異??梢詮?WA 代碼拋出或拋出WebAssembly.Exception
:表示從 WA 拋出到 JavaScript 的運行時異常,或者從 JavaScript 拋出到 WA 異常處理程序的運行時異常WebAssembly.LinkError
:表示在模塊實例化期間發(fā)生錯誤
b. 方法
WebAssembly.Memory()
:用于創(chuàng)建一個新的 Memory
內(nèi)存對象WebAssembly.CompileError()
:創(chuàng)建一個新的 WA 編譯錯誤對象WebAssembly.RuntimeError()
:創(chuàng)建一個新的 WA 運行時錯誤對象
0x01 結(jié)合 C/C++
使用 C 或 C++ 編寫一段代碼(以 C 為例)
| |
| #include<stdio.h> |
|
|
| int main(){ |
| printf("Hello, WebAssembly!"); |
| return 0; |
| } |
運行測試無誤后繼續(xù)
下載并安裝用于編譯 C/C++ 到 WA 的 Emscripten
詳細操作參考官方下載與安裝文檔:https://emscripten.org/docs/getting_started/downloads.html
使用命令 emcc main.c -s WASM=1 -o main.html
編譯
emcc
:Emscripten 提供的工具main.c
:基于 C 語言的代碼-s WASM=1
:指定輸出 WA-o main.html
:輸出 main.wasm、main.js 和 main.html 文件,按需使用
0x02 結(jié)合 C#
使用 C# 編寫一段代碼
| |
| public class Example |
| { |
| public static void Main() |
| { |
| System.Console.WriteLine("Hello, WebAssembly!"); |
| } |
| } |
安裝 .NET Core SDK、mono
使用命令 mcs --out:main.dll -t:library main.cs
將 C# 代碼編譯為 DLL
使用命令 mono --runtime=mono --aot=llvm main.dll
將 DLL 編譯為 WA
0x03 結(jié)合 Go
使用 Go 編寫一段代碼:
| |
| package main |
|
|
| import "fmt" |
|
|
| func main() { |
| fmt.Println("Hello, WebAssembly!") |
| } |
使用命令 GOOS=js GOARCH=wasm go build -o main.wasm main.go
通過 GOCC 將 main.go 編譯為 main.wasm
0x04 結(jié)合 Python
- 可以通過 py2wasm 工具將 Python 編譯為 WA,或使用 pyodide 直接在 JavaScript 中執(zhí)行 Python
a. py2wasm
使用 Python 編寫一段代碼:
| |
| if __name__ == '__main__': |
| print("Hello, WebAssembly!") |
使用命令 pip install py2wasm
安裝 py2wasm 工具
使用命令 py2wasm main.py -o main.wasm
將 main.py 編譯為 main.wasm
b. pyodide
在 HTML 頭中導入 pyodide.js 并編寫 Python 代碼
| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.js"></script> |
| </head> |
|
|
| <body> |
| <script> |
| async function main() { |
| let pyodide = await loadPyodide(); |
| await pyodide.loadPackage("numpy"); |
| let result = await pyodide.runPythonAsync(` |
| import numpy as np |
| np.sum([1, 2, 3, 4]) |
| `); |
| console.log(result); |
| } |
| main(); |
| </script> |
| </body> |
| </html> |
如果在 NodeJS 環(huán)境中,可以使用命令 npm install pyodide
導入
0x05 結(jié)合 Rust
參考自《將 Rust 代碼編譯為 WASM | 博客園-_zhiqiu》
使用命令 cargo add wasm-bindgen
添加依賴項
使用命令 rustup target add wasm32-unknown-unknown
安裝目標
使用 Rust 編寫一段代碼:
| |
| use wasm_bindgen::prelude::*; |
|
|
| |
| #[wasm_bindgen] |
| pub fn greet(name: &str) -> String { |
| format!("Hello, {}!", name) |
| } |
使用命令 cargo build --target wasm32-unknown-unknown --release
將 main.rs 編譯為 main.wasm 等文件
使用命令 wasm-bindgen --out-dir ./out --target web target/wasm32-unknown-unknown/release/lib_wasm.wasm
生成 JavaScript 綁定文件,并設置輸出目錄為 ./out
0x06 結(jié)合 TypeScript
- AssemblyScript 簡稱 AS,可以將 TypeScript 的嚴格變體編譯為 WA
- 具體操作方法參考 AS 官方文檔
-End-
本文作者:SRIGT
本文鏈接:https://www.cnblogs.com/SRIGT/p/18462925
版權(quán)聲明:本作品采用知識共享署名-非商業(yè)性使用-禁止演繹 2.5 中國大陸許可協(xié)議進行許可。
該文章在 2024/10/14 9:33:55 編輯過