一篇文章全面了解WebAssembly!!!以及如何把c/c++编译成WebAssembly,并在浏览器网页中加载运行WebAssembly

WebAssembly简介

官方描述:
WebAssembly是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C / C ++/rust/go等语言提供一个编译目标,以便它们可以在Web浏览器上运行。它被设计为可以与JavaScript共存,允许两者一起工作。

大白话:
WebAssembly是一门新的强类型编程语言,在浏览器中的有独立的虚拟机运行时。其他编程语言可以通过特定的WebAssembly编译器把源代码编译成WebAssembly的二进制字节码.wasm格式(不是机器码)。wasm格式是类似java代码编译成.class文件的中间代码,可以与js搭配和混合使用(可以在WebAssembly中调用js,同时也可以在js中调用WebAssembly)。

WebAssembly参考文档:https://developer.mozilla.org/zh-CN/docs/WebAssembly

可读文本.wat和.wasm二进制字节码补充说明

.wasm是WebAssembly二进制格式,WebAssembly工具链还有一个可读文本格式.wat或.wast。
因为.wasm本身是二进制格式,是无法看到代码或者生成的中间代码的,需要通过.wat或.wast文本格式来查看中间代码,方便调试。
使用https://github.com/webassembly/wabt可以把文本.wat转换为.wasm二进制字节码。

c/c++代码如何编译成.wasm字节码

可以使用Emscripten编译器把 c/c++代码编译成WebAssembly格式的二进制字节码
Emscripten官方:https://emscripten.org/index.html

c代码在线编译演示:https://wasdk.github.io/WasmFiddle/

如何加载和运行.wasm代码

WebAssembly目前还没有集成<script type='module'>或ES6的import语句,目前只能通过XMLHttpRequest或Fetch进行加载.wasm代码。

当前唯一的方式就是创建一个包含WebAssembly模块二进制代码的 ArrayBuffer 并且使用WebAssembly.instantiate()编译它。

Fetch方式加载.wasm字节码

假设网络上有一个叫做simple.wasm的WebAssembly模块。
我们可以使用fetch()全局函数来轻松地获取它,该函数返回一个可以解析为Response对象的promise。
我们可以使用arrayBuffer()函数把响应(response)转换为带类型数组,该函数返回一个可以解析为带类型数组的promise。
最后,我们使用WebAssembly.instantiate()函数一步实现编译和实例化带类型数组。

代码示例1

fetch('module.wasm').then(response =>
  response.arrayBuffer()).then(bytes =>
  WebAssembly.instantiate(bytes, importObject)).then(results => {
  // Do something with the compiled results!});

代码示例2(封装一个通用加载方法)

//封装一个通用加载方法function fetchAndInstantiate(url, importObject) {
  return fetch(url).then(response =>response.arrayBuffer()
  ).then(bytes =>WebAssembly.instantiate(bytes, importObject)
  ).then(results =>results.instance  );}//复用通用加载方法,简单实用fetchAndInstantiate('module.wasm', importObject).then(function(instance) {
  ...})

XMLHttpRequest方式加载.wasm字节码

假设我们的模块叫做simple.wasm。
1、创建一个 XMLHttpRequest() 实例,然后使用它的open() 方法来开启一个请求——设置请求方法为GET并且声明我们想要获取的文件路径。
2、关键之处在于使用responseType属性设置响应类型为’arraybuffer’。
3、接下来使用XMLHttpRequest.send()发送请求。
4、当响应已经完成下载之后,我们使用onload事件处理器来调用一个函数——在这个函数中,我们从response属性中得到数组缓存然后就像使用Fetch那样把它传递给WebAssembly.instantiate() 。

示例代码:

request = new XMLHttpRequest();request.open('GET', 'simple.wasm');request.responseType = 'arraybuffer';request.send();request.onload = function() {
  var bytes = request.response;
  WebAssembly.instantiate(bytes, importObject).then(results => {results.instance.exports.exported_func();//调用simple.wasm中的exported_func()方法
  });};

如果觉得博主写的还不错,欢迎“关注、点赞,收藏”一键三连!!

上一篇:java 读取文件路径空格和中文的处理


下一篇:ArcGIS Runtime SDK for WPF之SimpleRenderer无法添加、报错“图形符号无法序列化为 JSON”