WebAssembly 基础以及结合其他编程语言
				
									
					
					
						|  | 
							freeflydom 2024年10月14日 9:33
								本文热度 2377 | 
					
				 
				WebAssembly 基础
详情参考《WebAssembly | MDN》
(1)概述
- WebAssembly 简称 WASM 或 WA,是一种新的编码方式,可以在现代的 Web 浏览器中运行
- 可以通过编译器,把多种编程语言(如 C/C++、C#、Go、Python、Rust、TypeScript 等)编写的代码转化为 WA,并在浏览器中使用
- 特点:- 灵活度高:是一种低级的类汇编语言
- 体积较小:具有紧凑的二进制格式
- 性能提升:接近原生的性能运行
 
- WA 可以与 JavaScript 共存,允许两者一起工作
- WA 关键概念:- 模块:表示一个已经被浏览器编译为可执行机器码的 WA 二进制代码
- 内存:一个可变长的 ArrayBuffer
- 表格:一个可变长的类型化数组
- 实例:一个模块及其在运行时使用的所有状态(包括内存、表格和一系列导入值)
 
- 使用 WA 编写的相关应用:Figma 等
(2)加载与运行
- 通常,编译器将其他语言的代码编译成 .wasm 文件,以便在 WA 环境中使用 
- 在浏览器环境中,可以通过 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:包含已经由浏览器编译的无状态 WebAssembly 代码
- WebAssembly.Global:一个全局变量实例,可以被 JavaScript 和 importable/exportable 访问
- WebAssembly.Instance:有状态,是- WebAssembly.Module的一个可执行实例
- WebAssembly.Table:代表 WA 表格概念的 JavaScript 包装对象,具有类数组结构,存储了多个函数引用
- WebAssembly.Tag:定义了一种 WA 异常的类型,该异常可以从 WA 代码抛出或抛出
- WebAssembly.Exception:表示从 WA 抛出到 JavaScript 的运行时异常,或者从 JavaScript 抛出到 WA 异常处理程序的运行时异常
- WebAssembly.LinkError:表示在模块实例化期间发生错误
b. 方法
- WebAssembly.Memory():用于创建一个新的- Memory内存对象
- WebAssembly.CompileError():创建一个新的 WA 编译错误对象
- WebAssembly.RuntimeError():创建一个新的 WA 运行时错误对象
0x01 结合 C/C++
- 使用 C 或 C++ 编写一段代码(以 C 为例) | 
 |  |  | 
 | #include<stdio.h> |  | 
 | 
 |  | 
 | int main(){ |  | 
 | printf("Hello, WebAssembly!"); |  | 
 | return 0; |  | 
 | } |  
 
 - 运行测试无误后继续 
- 下载并安装用于编译 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 结合 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 结合 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 结合 Python
- 可以通过 py2wasm 工具将 Python 编译为 WA,或使用 pyodide 直接在 JavaScript 中执行 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 环境中,可以使用命令 npm install pyodide 导入
0x05 结合 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 结合 TypeScript
- AssemblyScript 简称 AS,可以将 TypeScript 的严格变体编译为 WA
- 具体操作方法参考 AS 官方文档
-End-
本文作者:SRIGT
本文链接:https://www.cnblogs.com/SRIGT/p/18462925
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
该文章在 2024/10/14 9:33:55 编辑过