JS调用WebAssembly编译.wasm文件实战:从C代码到浏览器执行

作者:流萤时间:2026-10-23 23:21:06浏览:646

本文详解如何在JavaScript中调用WebAssembly生成的.wasm文件。通过Emscripten将C代码编译为Side Module,利用Fetch API异步加载wasm模块,并在JS中实例化调用C函数。文章涵盖编译参数设置、本地服务器启动及完整的HTML调用示例,帮助开发者快速上手WebAssembly技术。

WebAssembly调用基础

WebAssembly(简称WASM)是一种在浏览器中运行的字节码技术,旨在提供接近原生性能的执行速度。关于其底层原理和优势,网络上已有大量详细介绍,此处不再赘述。

本文的核心目的是展示如何在JavaScript中调用并执行WASM模块。许多开发者在阅读官方WebAssembly API文档时感到困惑,因此本文旨在通过实际案例降低入门门槛。

为了帮助读者更快速地掌握这一较新的技术,我们将通过一个具体的C语言编译示例,演示完整的调用流程。

本例使用的是官方推荐的C/C++编译方式,将C代码编译为WebAssembly模块,以便JavaScript直接调用。

C代码编写与编译

以下是示例C代码:


 int add (int x, int y) {
 return x + y;
 }
 
 int square (int x) {
 return x * x;
 }

这段C代码虽然属性为C语言,但对于不熟悉字节码生成的读者可能会产生疑问:为什么没有main函数?

这是因为我们将C代码作为模块(Module)进行编译,而非独立的可执行程序,因此不需要main函数来启动。虽然官方文档提供了包含main函数的直接生成JS和HTML的示例,但这种方式往往过于臃肿,不利于集成。

采用模块化的方式更为推荐,它使得JavaScript能够更灵活、方便地调用底层C函数。

接下来,使用Emscripten工具链进行编译。具体命令如下:emcc math.c -Os -s WASM=1 -s SIDE_MODULE=1 -o math.wasm。

执行上述命令后,会生成math.wasm文件。如果尚未安装Emscripten,可参考博客中关于安装配置的相关文章。

获得math.wasm文件后,下一步就是在JavaScript中调用它。

JavaScript调用实现

新建一个math.html文件,并加入调用WASM的方法,具体代码如下:


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <h1>

 </h1>
 <script>
 /**
 * @param {String} path wasm 文件路径
 * @param {Object} imports 传递到 wasm 代码中的变量
 */
  function loadWebAssembly (path, imports = {}) {
   return fetch(path) // 加载文件
   .then(response => response.arrayBuffer()) // 转成 ArrayBuffer
   .then(buffer => WebAssembly.compile(buffer))
   .then(module => {
    imports.env = imports.env || {}

    // 开辟内存空间
    imports.env.memoryBase = imports.env.memoryBase || 0
    if (!imports.env.memory) {
    imports.env.memory = new WebAssembly.Memory({ initial: 256 })
    }

    // 创建变量映射表
    imports.env.tableBase = imports.env.tableBase || 0
    if (!imports.env.table) {
    // 在 MVP 版本中 element 只能是 "anyfunc"
    imports.env.table = new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
    }

    // 创建 WebAssembly 实例
    return new WebAssembly.Instance(module, imports)
   })
  }
  //调用
  loadWebAssembly('./math.wasm')
  .then(instance => {
   const add = instance.exports._add//取出c里面的方法
   const square = instance.exports._square//取出c里面的方法

   console.log('10 + 20 =', add(10, 20))
   console.log('3*3 =', square(3))
   console.log('(2 + 5)*2 =', square(add(2 + 5)))
  })

 </script>
</body>
</html>

请注意,示例中math.html与math.wasm文件位于同一目录下,路径需根据实际情况调整。

现在可以尝试在浏览器中打开查看。但需要注意的是,代码中使用了fetch方法,而fetch是网络请求接口,在本地直接打开HTML文件时无法使用,因此需要启动一个本地Web服务器。

本地服务器启动与运行

打开终端,输入 npm install -g serve 安装serve工具。

该命令用于下载并安装Web服务器工具。

安装完成后,使用 serve . 命令启动服务器,其中 . 表示当前目录。

这里的 . 代表启动当前工作目录下的静态文件服务。

启动完成后的效果如下所示:

WebAssembly调用基础

通过Web服务器访问页面,即可看到调用C语言方法后返回的计算结果。

WebAssembly调用基础

到此,关于如何在JavaScript中调用WebAssembly编译生成的.wasm文件的教程介绍完毕。更多相关内容请搜索本站历史文章或继续阅读后续文章,感谢大家的支持!

作者最新文章