webassembly入门

133 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情

一、前言

昨天初步了解了一下webassembly,今天就带大家伙走一遭开发流程,看看都需要什么步骤。

二、过程

1、准备工具链

先编译LLVM-底层虚拟机需要以下工具

准备git

准备Cmake

准备python 2.7x

Linux准备GCC, OSX准备Xcode, window装备vs 2015 community with update 3或以上版本

再编译LLVM变成webAssembly

准备Emscripten编译工具,需要安装到本地,官网那边是有教程的。

以上东西都准备好才能开始我们的编程之路,并将代码编译成wasm模块。

2、使用在线工具

本地安装成本比较大,大家如果只是想了解一下,试试水,可以先使用以下的在线工具进行学习,就不用本地安装和配置那么多东西了。

WasmFiddle工具

下面是界面展示,代码区域有两个,一个是c语言的,一个是js语言的,写完点击上方的build,就可以下载生成好的wasm文件了。

image.png

我在c语言的代码区域声明了两个函数,一个相加函数和一个求平方函数

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

int square (int x) {
  return x * x;
}

同时在js代码区域调用了add函数,并打印结果。

image.png

然后build并下载后,能得到一个program.wasm文件,文件名默认为program,可自定修改文件名。

image.png

3、拿到生成的wasm模块之后,在html中引用

第一二步的目的都是生成wasm模块文件。

由于是异步加载,我们需要定义函数loadWasm,作用是加载我们下载好的program.wasm文件,转换到缓冲区,开辟内存空间,定义好空间大小,如果超出为抛出rangeError异常,创建变量映射表,最后创建一个webassembly实例,供函数返回调用。参数的path指的是wasm文件路径,imports则是要传给wasm中的变量。

function loadWasm (path, imports = {}) {
    return fetch(path) // 加载文件
    .then(response => response.arrayBuffer()) // 转成 ArrayBuffer
    .then(buffer => WebAssembly.compile(buffer))
    .then(module => {
      imports.env = imports.env || {}
      // 开辟内存空间,开辟一个256页,每一页固定是64KiB
      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) {
        imports.env.table = new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
      }
      // 创建 WebAssembly 实例
      return new WebAssembly.Instance(module, imports)
    })
  }

然后我们调用一下该函数,同时在里面调用我们刚刚撰写的c语言函数square,每个函数都需要instance实例抛出,才能在js代码里进行调用,html和program.wasm在同级。

loadWebAssembly('program.wasm')
   .then(instance => {
        // 实例exports一下
        const add = instance.exports.add
        const square = instance.exports.square
        //调用c里面的方法
        console.log('3*3 =', square(3))
        console.log('(2 + 5)*2 =', square(add(2 + 5)))
  })

4、如何在浏览器中访问

刚刚的写好的html不能直接用浏览器打开,会报错误。

image.png

(1)准备web服务器

最低成本的就是用node搭建一个http-server本地服务器,可以用url的方式访问电脑的文件。

在装了node的前提下(node版本在v13及以上,不然http-server服务虽然能启动成功,但是访问会出错)

image.png

运行以下命令,安装http-server,如果切换了node版本,也必须重新安装

npm install -g http-server

image.png

然后切换到html和wasm所在的文件夹路径

比如我放在了我的路径是C:\Users\用户名\Desktop\webassembly> 就切换到该路径,然后输入http-server命令

image.png

生成以下这些信息后,就代表启动服务成功。

image.png

最后在浏览器输入http://127.0.0.1:8080/test.html,就能成功访问html文件了。 image.png

三、小结

能调用其他语言的代码,确实是比较nb的,后面有空看下如果要引入在项目里,那应该如何封装使用吧。大家伙有兴趣的也可以试一试。

ps: 我是地霊殿__三無,一天一更冲冲冲。