如何生成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 ...
随机推荐
- linux文件与目录管理笔记
### Linux文件与目录管理 ---------- 绝对路径: / 相对路径:不以/开头的 当前目录 . 上一个工作目录 - 用户主目录 ~ root账户的主目录是/root 其他用户是/home ...
- 1705: 小明在工作(zzuli)
题目描述 小明的工作是负责记录饭堂中正在排队的人的信息 在他的工作中会有三种可能的事件发生: 1.编号为id的学生加入到队伍的最后面 2.排在最前面的学生打完饭离开了队伍 3. ...
- Django的Session存储Redis环境配置
第一步:在项目目录下的settings.py中MIDDLEWARE中加上中间件: # session中间件Django项目默认启用Session 'django.contrib.sessions.mi ...
- java实现满天星swing&awt
一起有两个类 1.MyStar.java package day02; import java.awt.Color; import javax.swing.JFrame;import javax.sw ...
- Ajax增删改查-----------删 改
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【第一部分】04Leetcode刷题
一.反转链表 II /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; ...
- 查看python脚本的运行pid,让python脚本后台运行
ps -ef | grep Productor.py | grep -v grep # 先测试好 python3 /usr/local/software/ELK/Productor.py # 没问题 ...
- linux系统(CentOS7)虚拟机上安装oracle 11g,解决oracle图形界面卡住无法点击next问题
https://www.cnblogs.com/nichoc/p/6416475.html
- java keystore
JAVA有一个keystore用来存放私钥和证书,该文件是伴随JDK默认存在的,路径默认是/lib/security/cacerts,默认密码是changeit,实际上空密码也可以直接访问 其中cac ...
- ES6中const、let与var的对比详解
对比 声明方式 变量提升 作用域 初始值 重复定义const 否 块级 需要 不允许let 否 块级 不需要 不允许var 是 函数级 不需要 允许 变量提升:const 和 l ...