如何生成WebAssembly文件?
许多3D游戏都是用C/C++语言写的,如果能将C/C++语言编译成JavaScript代码,它们不就能在浏览器里运行了吗?
Emscripten的底层是LLVM编译器,Emscripten可以将c/c++编译成asm.js代码,也可以将c/c++编译成webAssembly,但却不能把asm.js转成wasm。想把asm.js编译成WebAssembly,需要借助Binaryen和WABT等工具。
asm.js是javascript的一个严格子集,它的变量一律都是静态类型,没有垃圾回收机制,通过TypedArray直接读写内存,在浏览器的运行速度比js更快。asm.js是文本,人类可读,比较直观。所有浏览器都支持asm.js,不会有兼容性问题。
// asm.js案例
function () {
"use asm";
function add (x, y) {
x = x | 0;
y = y | 0;
return x + y | 0;
}
function square (x) {
x = x | 0;
return x * x | 0;
}
return {
add: add,
square: square
};
}
WebAssembly是二进制字节码,因此运行速度更快、体积更小,但是有兼容性问题。
一、快速体验
// 在浏览器控制台输入下列代码,下面的一些列数字是WebAssembly 的二进制源码
WebAssembly.compile(new Uint8Array(`
00 61 73 6d 01 00 00 00 01 0c 02 60 02 7f 7f 01
7f 60 01 7f 01 7f 03 03 02 00 01 07 10 02 03 61
64 64 00 00 06 73 71 75 61 72 65 00 01 0a 13 02
08 00 20 00 20 01 6a 0f 0b 08 00 20 00 20 00 6c
0f 0b`.trim().split(/[\s\r\n]+/g).map(str => parseInt(str, 16))
)).then(module => {
const instance = new WebAssembly.Instance(module)
const { add, square } = instance.exports
console.log('2 + 4 =', add(2, 4))
console.log('3^2 =', square(3))
console.log('(2 + 5)^2 =', square(add(2 + 5)))
})
上边的二进制源码一行 16 个数,有 4 行零两个,一共有 66 个数;每个数都是 8 位无符号十六进制整数,一共占66Byte。把字符串转成ArrayBuffer,先将字符串分割成普通数组,然后将普通数组转成8位无符号整数的数组。如果WebAssembly.compile返回的Promise fulfilled了,resolve方法的第一个参数就是WebAssembly的模块对象,是WebAssembly.Module的实例。WebAssembly.Instance将模块对象转成WebAssembly实例,通过instance.exports可以拿到wasm代码输出的接口,剩下的代码就和普通javascript一样了。
只有通过js代码来编译、实例化才可以调用webAssembly的接口。WebAssembly更适合用于写模块,承接各种复杂的计算,如图像处理、3D运算、语音识别、视音频编码解码这种工作,主体程序还是要用javascript来写的。
二、安装环境
1、git
2、CMake
3、vscode/xcode
4、python。
三、编译Emscripten
git clone https://github.com/juj/emsdk.git cd emsdk
# 适用于os系统 ./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit ./emsdk activate --global --build=Release sdk-incoming-64bit binaryen-master-64bit # 该命令会经常用到 source ./emsdk_env.sh
四、运行代码
# 把cpp文件编译成wasm文件,html文件 emcc -o webAssembly/test6/hello.html webAssembly/test6/hello.c -O3 -s WASM= --shell-file webAssembly/test6/html_template/shell_minimal.html # 使用一个支持WebAssembly的浏览器运行生成的html文件 emrun webAssembly/test6/hello.html # 如果不知道命令选项的含义 emcc --help
五、小尝试
这里主要汇集了自己初学webAssembly练习的C++代码。
六、参考链接
https://developer.mozilla.org/zh-CN/docs/WebAssembly/C_to_wasm
http://www.ruanyifeng.com/blog/2017/09/asmjs_emscripten.html
https://segmentfault.com/a/1190000008402872
https://developer.mozilla.org/zh-CN/docs/WebAssembly/Using_the_JavaScript_API
http://webassembly.org/
https://cunzaizhuyi.github.io/WebAssembly-LinkError/
在线写webAssembly,https://webassembly.studio/?f=aakxyho2ho
如何生成WebAssembly文件?的更多相关文章
- Android 解析XML文件和生成XML文件
解析XML文件 public static void initXML(Context context) { //can't create in /data/media/0 because permis ...
- SQL*Plus生成html文件
最近使用SQL*Plus命令生成html文件,遇到一些有意思的知识点,顺便记录一下,方便以后需要的时候而这些知识点又忘记而捉急.好记性不如烂笔头吗! 为什么要用SQL*Plus生成html文件? ...
- vim保存文件时,生成.un~文件
在用vim保存文件时,文件夹下生成.un~文件 怎么删除这些文件呢 在网上搜索的答案: http://stackoverflow.com/questions/15660669/what-is-a-un ...
- WPF根据Oracle数据库的表,生成CS文件小工具
开发小工具的原因: 1.我们公司的开发是客户端用C#,服务端用Java,前后台在通讯交互的时候,会用到Oracle数据库的字段,因为服务器端有公司总经理开发的一个根据Oracle数据库的表生成的cla ...
- 简单生成svg文件
this.fileSaveSync = function (file, data) { var fs = require('fs-extra'); fs.writeFileSync(file, dat ...
- 使用Free Spire.Presentation生成PowerPoint文件
使用Free Spire.Presentation生成PowerPoint文件 前言 之前有写过一篇使用Free Spire.XLS生成图表的文章,朋友圈内反应还不错,都希望我能继续写下去,把类似 ...
- caffe的python接口学习(5):生成deploy文件
如果要把训练好的模型拿来测试新的图片,那必须得要一个deploy.prototxt文件,这个文件实际上和test.prototxt文件差不多,只是头尾不相同而也.deploy文件没有第一层数据输入层, ...
- 利用 autoconf 和 automake 生成 Makefile 文件
一.相关概念的介绍 什么是 Makefile?怎么书写 Makefile?竟然有工具可以自动生成 Makefile?怎么生成啊?开始的时候,我有这么多疑问,所以,必须得先把基本的概念搞个清楚. 1.M ...
- linux下使用automake工具自动生成makefile文件
linux环境下,当项目工程很大的时候,编译的过程很复杂,所以需要使用make工具,自动进行编译安装,但是手写makefile文件比较复杂,所幸在GNU的计划中,设计出了一种叫做Autoconf/Au ...
随机推荐
- Zookeeper安装(本地,伪分布式,集群)
概述 ZooKeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization).命名服务(Namin ...
- OrCAD Capture CIS 16.6 导出BOM
OrCAD Capture CIS 16.6 一.选择设计文件:菜单:Tools > Bill of Materials... 二.Bill of Materials > Open in ...
- time与datetime模块
在python中,通常用下面几种方式来表示时间: 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. 格式化的时间字符串(format s ...
- python 0007
#coding='utf-8'# import re import os def get_list(): list_file=[] for f in os.listdir(): if f.endswi ...
- 通过expdp和impdp将Oracle11g数据导入到Oracle10g中
1 导出过程 1.1 查看目录: select * from dba_directories; 1.2 将目录的操作权限赋值给指定的用户(不执行次步骤可能会出现权限问题): grant read,wr ...
- expdp、impdp 使用sys用户操作时的注意事项
https://blog.csdn.net/ctypyb2002/article/details/78420711
- Chino的数列
题解: 一道练代码能力的题目.. 首先很显然他是一道平衡树裸题 第5个操作是势能分析维护最大值最小值就可以了 另外设置虚点和noip2017队列那题一样(不过我只写过线段树) 具体细节: 1.内存池, ...
- python排列组合之itertools模块
1. 参考 几个有用的python函数 (笛卡尔积, 排列, 组合) 9.7. itertools — Functions creating iterators for efficient loopi ...
- 记JS一个错误,
在定义变量时候,如果直接定义 var obj=null;那么,在转码时候,比如转为base64,此时或出现特殊的文字(也是汉字,只是很少见少用的文字,而且,出现的文字是根据你给obj赋值决定的,) 由 ...
- 【译】异步JavaScript的演变史:从回调到Promises再到Async/Await
我最喜欢的网站之一是BerkshireHathaway.com--它简单,有效,并且自1997年推出以来一直正常运行.更值得注意的是,在过去的20年中,这个网站很有可能从未出现过错误.为什么?因为它都 ...