首先,什么是WebAssembly?

根据维基百科上面的解释:WebAssembly或称wasm是一个实验性的低级编程语言,应用于浏览器内的客户端。WebAssembly是便携式的抽象语法树,被设计来提供比JavaScript更快速的编译及运行。WebAssembly将让开发者能运用自己熟悉的编程语言(目前主要是C/C++)编译,再藉JavaScript引擎在浏览器内运行。

http://webassembly.org/

按照博主的理解,WebAssembly应该是种可以被浏览器运行的二进制程序。嗯

如何使用?

根据WebAssembly官方的说明,其实就只用安装一个叫emcc的编译器就可以编译了,但是他们也推出了emsdk这个工具,博主感觉还是不错的东西。
具体可以看官方的Getting Started
安装结束后就可以开始开发了。

WebAssembly的可执行文件后缀名为.wasm但是就目前的情况来说,必须由js来调用程序。

所以当前WebAssembly的调用思路博主认为是这样的:js发起http请求拉取wasm文件,然后用创建WebAssembly实例(其中涉及内存分配等等问题),将文件载入到实例中,然后导出函数接口,最后调用函数。

编译出你的wasm二进制文件

根据官方推荐的sdk构建方式进行构建: http://webassembly.org/getting-started/developers-guide/

但是,官方推荐使用的emcc hello.c -s WASM=1 -o hello.html博主不推荐使用,这会生成一堆无用的文件,而且生成的这个hello.html也无法运行。

所以博主通常使用这个emcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -o hello.wasm来构建。
这样我们得到的就是干干净净的wasm。

网页中拉取你的wasm程序

博主推荐MDN提供的思路实现。

这是博主使用的调用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

function loadWebAssembly(filename, imports = {}) {
return fetch(filename)
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer))
.then(module => {
imports.env = imports.env || {}
Object.assign(imports.env, {
memoryBase: 0,
tableBase: 0,
memory: new WebAssembly.Memory({
initial: 256,
maximum: 256
}),
table: new WebAssembly.Table({
initial: 0,
maximum: 0,
element: 'anyfunc'
})
})
return new WebAssembly.Instance(module, imports)
})
}

loadWebAssembly('example.wasm')
.then(instance => {
const example = instance.exports._example;
example(100);
})

就目前而言,wasm调用还是非常复杂的。

关于它与asm.js和wast。

asm.js是cpp编译至wasm的一个中间步骤,博主更推荐使用asm.js。wast具体是干什么的不太清楚,更像是人能读懂的伪程序?

关于其他的一些坑

博主一直无法实现字符串的操作。也就是目前博主,只实现了整型数据的传入返回。
这是一些有意思的现象:

  1. long long在其中也是不被支持
  2. time.h 内的很多东西不被支持
  3. 编译器对c++的兼容性比c差

JavaScript本身作为一种弱类型的语言,和c语言对接的时候,强制类型转换本身就是一个大坑。

所以,WebAssembly到底适合什么样的使用场景?

  1. 适合进行复杂算法的执行,而且直接封装。数据丢进去,然后出结果,效率是比原生js要好
  2. 安全性较高的数据处理,比如某种加密算法,原始数据传入后,经过黑盒直接出结果。但是安全性目前还没看到可行性验证。
  3. webGL游戏

作为其他常用的操作,还是老老实实的写js吧,就目前来说,这东西使用成本很高的,坑非常多。而且优质文章资源非常少,版本API革新非常快