WebAssembly 基础以及结合其他编程语言

0x00 WebAssembly 基础

详情参考《WebAssembly | MDN》

(1)概述

  • WebAssembly 简称 WASM 或 WA,是一种新的编码方式,可以在现代的 Web 浏览器中运行
  • 可以通过编译器,把多种编程语言(如 C/C++、C#、Go、Python、Rust、TypeScript 等)编写的代码转化为 WA,并在浏览器中使用
  • 特点:
    • 灵活度高:是一种低级的类汇编语言
    • 体积较小:具有紧凑的二进制格式
    • 性能提升:接近原生的性能运行
  • WA 可以与 JavaScript 共存,允许两者一起工作
  • WA 关键概念:
    • 模块:表示一个已经被浏览器编译为可执行机器码的 WA 二进制代码
    • 内存:一个可变长的 ArrayBuffer
    • 表格:一个可变长的类型化数组
    • 实例:一个模块及其在运行时使用的所有状态(包括内存、表格和一系列导入值)
  • 使用 WA 编写的相关应用:Figma

(2)加载与运行

  1. 通常,编译器将其他语言的代码编译成 .wasm 文件,以便在 WA 环境中使用

  2. 在浏览器环境中,可以通过 AJAX 导入外部文件,如导入 .wasm 文件

    js 复制代码
    fetch("main.wasm");
  3. JavaScript 中的 WebAssembly 对象是所有 WA 相关功能的命名空间,其中 WebAssembly.compile / WebAssembly.instantiateWebAssembly.compileStreaming / WebAssembly.instantiateStreaming 方法组合可以用于加载和运行 WA 代码

    js 复制代码
    fetch("main.wasm")
      .then((response) => response.arrayBuffer())
      .then((bytes) => WebAssembly.compile(bytes))
      .then((module) => {
        const instance = new WebAssembly.Instance(module);
        console.log(instance.exports);
      });

    js 复制代码
    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++

  1. 使用 C 或 C++ 编写一段代码(以 C 为例)

    c++ 复制代码
    // filename: main.c
    #include<stdio.h>
    
    int main(){
      printf("Hello, WebAssembly!");
      return 0;
    }

    运行测试无误后继续

  2. 下载并安装用于编译 C/C++ 到 WA 的 Emscripten

    详细操作参考官方下载与安装文档:https://emscripten.org/docs/getting_started/downloads.html

  3. 使用命令 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#

  1. 使用 C# 编写一段代码

    c# 复制代码
    // filename: main.cs
    public class Example
    {
      public static void Main()
      {
        System.Console.WriteLine("Hello, WebAssembly!");
      }
    }
  2. 安装 .NET Core SDK、mono

  3. 使用命令 mcs --out:main.dll -t:library main.cs 将 C# 代码编译为 DLL

  4. 使用命令 mono --runtime=mono --aot=llvm main.dll 将 DLL 编译为 WA

0x03 结合 Go

  1. 使用 Go 编写一段代码:

    go 复制代码
    // filename: main.go
    package main
    
    import "fmt"
    
    func main() {
      fmt.Println("Hello, WebAssembly!")
    }
  2. 使用命令 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

  1. 使用 Python 编写一段代码:

    python 复制代码
    # filename: main.py
    if __name__ == '__main__':
        print("Hello, WebAssembly!")
  2. 使用命令 pip install py2wasm 安装 py2wasm 工具

  3. 使用命令 py2wasm main.py -o main.wasmmain.py 编译为 main.wasm

b. pyodide

在 HTML 头中导入 pyodide.js 并编写 Python 代码

html 复制代码
<!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"); // 加载一个 Python 库
        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》

  1. 使用命令 cargo add wasm-bindgen 添加依赖项

  2. 使用命令 rustup target add wasm32-unknown-unknown 安装目标

  3. 使用 Rust 编写一段代码:

    rust 复制代码
    // filename: main.rs
    use wasm_bindgen::prelude::*;
    
    // 使用 #[wasm_bindgen] 宏来导出函数到 JavaScript
    #[wasm_bindgen]
    pub fn greet(name: &str) -> String {
      format!("Hello, {}!", name)
    }
  4. 使用命令 cargo build --target wasm32-unknown-unknown --releasemain.rs 编译为 main.wasm 等文件

  5. 使用命令 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-

相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax