1. WebAssembly技术介绍

WebAssembly是2015年诞生的一项新的技术,在2015年7月,Wasm首次对外公开,并正式开始设计,同年,W3C成立了Wasm社区小组(成员包括Chrome、Edge、Firefox和WebKit),致力于推动Wasm技术的早期发展。

wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式。

WebAssembly的中文官网:http://webassembly.org.cn/

来至官网的介绍:

WebAssembly 是由主流浏览器厂商组成的 W3C 社区团体 制定的一个新的规范。

高效
WebAssembly 有一套完整的语义,实际上 wasm 是体积小且加载快的二进制格式, 其目标就是充分发挥硬件能力以达到原生执行效率

安全
WebAssembly 运行在一个沙箱化的执行环境中,甚至可以在现有的 JavaScript 虚拟机中实现。在web环境中,WebAssembly将会严格遵守同源策略以及浏览器安全策略。

开放
WebAssembly 设计了一个非常规整的文本格式用来、调试、测试、实验、优化、学习、教学或者编写程序。可以以这种文本格式在web页面上查看wasm模块的源码。

标准
WebAssembly 在 web 中被设计成无版本、特性可测试、向后兼容的。WebAssembly 可以被 JavaScript 调用,进入 JavaScript 上下文,也可以像 Web API 一样调用浏览器的功能。当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。

由于不同的计算机 CPU 架构不同,机器码标准有所差别,常见的架构有 x86、AMD 64、ARM,因此高级语言编译成可执行代码时需要指定目标架构。

WebAssembly 抹平了不同 CPU 架构的机器码,WebAssembly 的机器码不能放在任何一个平台上运行,但由于非常接近机器码,可以被非常快速的翻译为对应架构的机器码。因此,WebAssembly 的运行速度和机器码非常接近。

通过官网的介绍看出,WebAssembly技术的目的就是提高web端代码性能,总所周知C/C++语言的运行性能一直是天花板,许多 3D 游戏,大型图形编辑相关的工具软件都是用 C/C++ 语言写的,如果能把C/C++代码搬到web端运行,那么理论上可以大大提高web端的运行效率。

要使用WebAssembly技术,需要先安装Emscripten编译器,这个Emscripten编译器可以将 C/C++ 代码编译成 JS 代码,但不是普通的 JS,而是一种叫做 asm.js 的 JavaScript 变体。

在WebAssembly官网有介绍如何编译安装Emscripten SDK,网站地址: http://webassembly.org.cn/getting-started/developers-guide/

Emscripten的官网也有详细介绍: https://emscripten.org/docs/getting_started/downloads.html

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rFV9uRc2-1653283486943)(https://xl-boke-img.oss-cn-beijing.aliyuncs.com/img/image-20220216140034973.png)]

2. 安装Emscripten编译器

官网上有步骤介绍,这里再把安装的步骤做个总结。

注: 当前是在win10 64 位环境下操作。

(1)需要先安装python环境,推荐安装python3.X,因为Emscripten编译器里用到了python命令。

python环境安装看这里:

https://xiaolong.blog.csdn.net/article/details/118497618

https://xiaolong.blog.csdn.net/article/details/118529329

(2)安装Git工具,因为需要使用git命令在线从仓库下载需要的文件。

Git工具安装看这里:翻到Git工具安装章节。

https://blog.csdn.net/xiaolong1126626497/article/details/116541069

(3)从GitHub仓库下载编译器项目文件,选择一个英文目录,鼠标右键,打开git命令行。(安装完Git工具后会自动关关键鼠标右键)

运行下面命令进行下载,过程中需要等待一段时间。

git clone https://github.com/emscripten-core/emsdk.git

下载成功后,当前目录下会出现一个emsdk目录。

(4)在当前目录下的文件夹地址栏里输入cmd,按下回车,快速打开cmd命令终端。

输入命令进入到emdk目录下。

cd emsdk

(5)安装最新的SDK并激活,在当前命令行继续输入命令。 注: 安装要一点时间,需要耐心等待,具体速度看网络情况。

emsdk install latest
emsdk activate latest --permanent

完成输出的过程:

C:\Qt\emsdk>emsdk install latest
Installing SDK 'sdk-releases-upstream-37fc7647c754ac9a28ad588c143b82286de0ef71-64bit'..
Skipped installing node-12.18.1-64bit, already installed.
Skipped installing python-3.7.4-pywin32-64bit, already installed.
Skipped installing java-8.152-64bit, already installed.
Installing tool 'releases-upstream-37fc7647c754ac9a28ad588c143b82286de0ef71-64bit'..
Downloading: C:/Qt/emsdk/zips/37fc7647c754ac9a28ad588c143b82286de0ef71-wasm-binaries.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/37fc7647c754ac9a28ad588c143b82286de0ef71/wasm-binaries.zip, 476624087 Bytes
Unpacking 'C:/Qt/emsdk/zips/37fc7647c754ac9a28ad588c143b82286de0ef71-wasm-binaries.zip' to 'C:/Qt/emsdk/upstream'
Done installing tool 'releases-upstream-37fc7647c754ac9a28ad588c143b82286de0ef71-64bit'.
Running post-install step: npm ci ...
Running post-install step: npm install google-closure-compiler-windows
Done running: npm ci
Done installing SDK 'sdk-releases-upstream-37fc7647c754ac9a28ad588c143b82286de0ef71-64bit'.C:\Qt\emsdk>emsdk activate latest --permanent
Registering active Emscripten environment permanentlySetting the following tools as active:node-12.18.1-64bitpython-3.7.4-pywin32-64bitjava-8.152-64bitreleases-upstream-37fc7647c754ac9a28ad588c143b82286de0ef71-64bitSetting environment variables:
PATH = C:\Qt\emsdk;C:\Qt\emsdk\node\12.18.1_64bit\bin;C:\Qt\emsdk\python\3.7.4-pywin32_64bit;C:\Qt\emsdk\java\8.152_64bit\bin;C:\Qt\emsdk\upstream\emscripten;C:\Users\11266\AppData\Local\Programs\Python\Python38-32\Scripts\;C:\Users\11266\AppData\Local\Programs\Python\Python38-32\;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;C:\Users\11266\AppData\Local\Programs\Microsoft VS Code\bin;C:\MinGW\i686-8.1.0-release-posix-dwarf-rt_v6-rev0\mingw32\bin;C:\OpenCV_3.4.7\OpenCV-MinGW-Build-OpenCV-3.4.7\x86\mingw\bin;%USERPROFILE%\.dotnet\tools;C:\FFMPEG\ffmpeg_x86_4.2.2\bin;C:\FFMPEG\ffmpeg_x86_x64_3.3.2\bin;C:\Users\11266\AppData\Roaming\npm
Global environment variables up to date

(6)在命令行输入em++ -v测试编译器是否安装成功。

出现以下提示,表示编译器已经安装成功。

C:\Qt\emsdk>emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.10
clang version 12.0.0 (Cswircachegitchromium.googlesource.com-external-github.com-llvm-llvm--project 445289aa63e1b82b9eea6497fb2d0443813a9d4e)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:/Qt/emsdk/upstream/bin
shared:INFO: (Emscripten: Running sanity checks)C:\Qt\emsdk>em++ -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.10
clang version 12.0.0 (Cswircachegitchromium.googlesource.com-external-github.com-llvm-llvm--project 445289aa63e1b82b9eea6497fb2d0443813a9d4e)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:/Qt/emsdk/upstream/bin
shared:INFO: (Emscripten: Running sanity checks)C:\Qt\emsdk>

(7)这时可以先关闭当前终端,再重新开一个新终端,运行emcc或者em++查看帮助,会出现以下提示。

C:\Users\11266>cd /d D:\linux-share-dir\tmp\WebAssembly_TestCodeD:\linux-share-dir\tmp\WebAssembly_TestCode>emcc -help==============================================================================
Welcome to Emscripten!This is the first time any of the Emscripten tools has been run.A settings file has been copied to ~/.emscripten, at absolute path: C:\Users\11266\.emscriptenIt contains our best guesses for the important paths, which are:LLVM_ROOT       = /usr/binNODE_JS         = C:\Program Files\nodejs\node.exeEMSCRIPTEN_ROOT = C:\Qt\emsdk\upstream\emscriptenPlease edit the file if any of those are incorrect.This command will now exit. When you are done editing those paths, re-run it.
==============================================================================

打开当前系统的用户目录,会看到一个.emscripten文件。这个文件里存放了编译器需要的环境变量和路径。

如果后续运行emcc或者em++命令编译程序时报错,例如:

D:\linux-share-dir\tmp\WebAssembly_TestCode>emcc hello.cpp -Os -s WASM=1 -s SIDE_MODULE=1 -o hello.wasm
shared:ERROR: BINARYEN_ROOT is set to empty value in C:\Users\11266/.emscriptenD:\linux-share-dir\tmp\WebAssembly_TestCode>emcc hello.cpp -Os -s WASM=1 -s SIDE_MODULE=1 -o hello.wasm
cache:INFO: generating system asset: is_vanilla.txt... (this will be cached in "C:\Users\11266\.emscripten_cache\is_vanilla.txt" for subsequent builds)
shared:ERROR: llc executable not found at `C:\Users\11266/upstream/bin\llc.exe`

解决办法:将.emscripten文件里的所有路径改成绝对路径。

例如:原来的路径

import os
emsdk_path = os.path.dirname(os.environ.get('EM_CONFIG')).replace('\\', '/')
NODE_JS = emsdk_path + '/node/12.18.1_64bit/bin/node.exe'
PYTHON = emsdk_path + '/python/3.7.4-pywin32_64bit/python.exe'
JAVA = emsdk_path + '/java/8.152_64bit/bin/java.exe'
LLVM_ROOT = emsdk_path + '/upstream/bin'
BINARYEN_ROOT = emsdk_path + '/upstream'
EMSCRIPTEN_ROOT = emsdk_path + '/upstream/emscripten'
TEMP_DIR = emsdk_path + '/tmp'
COMPILER_ENGINE = NODE_JS
JS_ENGINES = [NODE_JS]

修改后的配置文件路径:

import os
NODE_JS = 'C:/Qt/emsdk/node/12.18.1_64bit/bin/node.exe'
PYTHON = 'C:/Qt/emsdk/python/3.7.4-pywin32_64bit/python.exe'
JAVA = 'C:/Qt/emsdk/java/8.152_64bit/bin/java.exe'
LLVM_ROOT = 'C:/Qt/emsdk/upstream/bin'
BINARYEN_ROOT = 'C:/Qt/emsdk/upstream'
EMSCRIPTEN_ROOT = 'C:/Qt/emsdk/upstream/emscripten'
TEMP_DIR = 'C:/Qt/emsdk/tmp'
COMPILER_ENGINE = NODE_JS
JS_ENGINES = [NODE_JS]

再重新运行即可:

D:\linux-share-dir\tmp\WebAssembly_TestCode>emcc hello.cpp -Os -s WASM=1 -s SIDE_MODULE=1 -o hello.wasm
cache:INFO: generating system asset: generated_struct_info.json... (this will be cached in "C:\Users\11266\.emscripten_cache\wasm-obj-pic\generated_struct_info.json" for subsequent builds)
cache:INFO:  - ok

3. 编写C/C++代码浏览器运行测试

(1)编写一个简单的C/C++代码

#include <stdio.h>
int main()
{printf("Hello World! \n");printf("WebAssembly 牛逼!\n");return 0;
}

(2)使用emcc编译编译

D:\>cd /d D:\linux-share-dir\tmp\WebAssembly_TestCodeD:\linux-share-dir\tmp\WebAssembly_TestCode>emcc hello.cpp -s WASM=1 -O3 -o hello-emcc.js
D:\linux-share-dir\tmp\WebAssembly_TestCode>emcc hello.cpp -s WASM=1 -O3 -o hello-emcc.html

编译成功之后,在目录下会生成:js,html,wasm 等3个文件。

(3)开一个HTTP服务器,测试网页运行效果

在当前编译目录,使用python开一个HTTP服务器。

D:\linux-share-dir\tmp\WebAssembly_TestCode>python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

打开Edge浏览器(win10自带的浏览器),输入http://127.0.1:8000。

选择hello-emcc.html文件打开。下面是运行效果。

也可以使用 emrun 命令来创建一个 http 协议的 web server 展示编译后的文件,和前面python命令的功能类似。

$ emrun --no_browser --port 8080

4. 编写C/C++代码给前端调用测试

(1)编写一个函数,用于测试调用

#include <emscripten.h>
#include <stdio.h>int func_square(int x)
{return x * x;
}int func_sum(int x, int y)
{return x + y;
}char* func_string(char* str)
{return str;
}

(2)编译成wasm文件

D:\linux-share-dir\tmp\WebAssembly_TestCode>emcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -o hello.wasm

(3)编写一个js文件。名称为: loader.js

function loadWebAssembly(filename, imports = {}) {return fetch(filename).then(response => response.arrayBuffer()).then(buffer => {imports.env = imports.env || {}Object.assign(imports.env, {memoryBase: 0,tableBase: 0,__memory_base: 0,__table_base: 0,memory: new WebAssembly.Memory({ initial: 256, maximum: 256 }),table: new WebAssembly.Table({ initial: 0, maximum: 0, element: 'anyfunc' })})return WebAssembly.instantiate(buffer, imports)}).then(result => result.instance )
}function loadJS (url, imports = {}) {return fetch(url).then(response => response.text()).then(code => new Function('imports', `return (${code})()`)).then(factory => ({ exports: factory(imports) }))
}

(4)编写一个HTML文件调用函数接口 : 例如: index.html

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Compile C to WebAssembly</title><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="apple-mobile-web-app-status-bar-style" content="black" /><meta name="apple-touch-fullscreen" content="yes" /><meta name="format-detection" content="telephone=no, email=no" /><script src="./loader.js"></script>
</head><body><h1>Compile C to WebAssembly</h1><p>The test result can be found in console.</p><script>loadWebAssembly('./hello.wasm').then(instance => {const func_square = instance.exports.func_squareconst func_sum = instance.exports.func_sumconst func_string = instance.exports.func_stringconsole.log('10^2 =', func_square(2))console.log('100+100 =', func_sum(100,100))console.log('这是传入字符串=', func_string("12345677890abcdefg"))})</script>
</body>
</html>

(5)启动http服务器,访问测试。

python -m http.server

打开谷歌浏览器输入地址访问: http://127.0.0.1:8000/index.html

运行后,按下F12,查看控制台的输出。

注意:如果要反复修改HTML文件测试结果,浏览器最好打开无痕模式进行测试。

在浏览器里可以看到wasm转成wast文本格式的代码,从代码里可以看到导出的函数。

5. webassembly在线调试工具

地址:https://wasdk.github.io/WasmFiddle/

6. wasm2wast工具安装

wasm2wast这个工具是将 WebAssembly 二进制转换为 S-expressions。他是命令行工具,一个二进制文件作为输入,输出一个包含可以读文本的文件。开发者可以编辑文本文件,然后再将其转换为二进制文件,比如优化算法、追踪问题、插入调试语句等等。

**地址:**https://github.com/WebAssembly/wabt

用法示例:

wast2wasm demo.wast -o demo.wasmwasm2wast demo.wasm -o demo.wast

7. emsdk常用命令介绍

1)emcc -v 显示安装的版本号(2)em++ -v 显示安装的版本号(3)emsdk update   更新emssk库到最新版(4)emsdk list --old  查看emsdk历史版本号列表(5)emsdk list --old > sdklist.txt  将历史版本号写入到sdklist.txt文件中(6)emsdk install <版本号> 安装对应版本号的sdk tool
例如: emsdk install 1.39.77)emsdk install latest 安装最新版本号的std tool(8)emsdk activate <版本号>  激活对应版本号的std tool ,也就是设置当前使用的版本
例如:emsdk activate --embedded 1.39.7 --permanent(9)emsdk uninstall <版本号>  卸载对应版本号的sdk tool(10)emsdk help  或者  emsdk --help   查看帮助

8. 总结

WebAssembly技术_在Web端运行C与C++程序(win10)相关推荐

  1. WebAssembly技术_在Web端运行C与C++程序(ubuntu18.04)

    1. 前言 WebAssembly/wasm WebAssembly 或者 wasm 是一个可移植.体积小.加载快并且兼容 Web 的全新格式. WebAssembly(缩写为 wasm)是一种使用非 ...

  2. 身份验证错误错误指定的句柄无效_基于 Web 端的人脸识别身份验证「实践」

    作者:沫沫 政采云前端团队 转发链接:https://mp.weixin.qq.com/s/fRDpXixnLIy9c0Uh2tMezQ 前言 近些年来,随着生物识别技术的逐渐成熟,基于深度学习的人脸 ...

  3. Webassembly 学习3 -- 打造web端的aac 播放器

    1.引言 aac 是很常见的音频格式,压缩率比mp3 还高,H5 支持从audio 标签文件读取aac 文件并播放,但不支持从网络流中直接读取.这里借助webassembly 技术,将aac 转码成p ...

  4. 技术教程 | 基于 Web 端的屏幕共享实践

    屏幕共享的英文叫做 DesktopSharing,通俗点讲就是将自己电脑的画面分享给其他人, 被分享的可以是整个电脑屏幕.应用程序或者某一个打开的网页等等. 而随着音视频领域的深入发展,完备的功能在用 ...

  5. java web网银支付_农行web端网银支付java接口文件及demo

    [实例简介] 农行web端网银支付java接口文件及demo [实例截图] [核心代码] JAVA接口包-升级版 └── JAVA接口包-升级版 ├── ABCIcon │   ├── abcicon ...

  6. python是脚本语言、需要编译器编译执行_使用Notepad++编译运行C/C++/Python程序

    对我来说,比较常用的是C/C++/Python. 使用Notepad++编译运行单个源文件的C/C++/Python,比使用复杂的IDE更加快捷. 想要让Notepad++能够做到编译运行C/C++/ ...

  7. cmd 将文件夹下文件剪切到另外一个文件_手把手教你运行第一个 Java 程序,看不懂你来骂我!...

    码字不易,对你有帮助 **点赞 /转发↪️/关注 ** 支持一下作者 微信搜公众号:不会编程的程序圆br/>看更多干货,获取第一时间更新 在运行第一个 java 程序之前,你需要先将 java ...

  8. win10运行C语言的程序,win10系统运行软件提示应用程序发生异常0xc0000409的具体教程...

    有关win10系统运行软件提示应用程序发生异常0xc0000409的操作方法想必大家有所耳闻.但是能够对win10系统运行软件提示应用程序发生异常0xc0000409进行实际操作的人却不多.其实解决w ...

  9. vantui框架switch上显示提示文字_以web端为例:我的交互设计细节手册(上)

    这篇文章所列举的案例内容都来源于我实际工作,有踩过的坑也有经过思考提出的解决方案,在这里拿出来分享给大家,如果有不同意见可以在下方评论区进行留言,一起探讨学习. 本文主要总结了我在实际交互设计中的所遇 ...

最新文章

  1. 全国计算机等级考试一级ps考试试题,计算机等级考试一级ps考前试题及答案
  2. Android调试的必杀技——反汇编
  3. linux——虚拟机的图形安装、管理以及快照
  4. 最全的C#图片处理类ImageHelper.cs
  5. 1200plc 虚拟轴_泡沫轴,哪里酸痛滚哪里,还能滚出完美曲线!
  6. VTK:Rendering之Mace
  7. 《开源思索集》一如何更有效地学习开源项目的代码?
  8. 配置mysql使其允许外部ip进行登录
  9. 面试官:Redis中的缓冲区了解吗
  10. 求01矩阵中的最大的正方形面积
  11. 联手三年,获取数千名客户,阿里云如何重构Elastic开放免费的技术?
  12. CSDN 创始人蒋涛:选择长沙作“大本营”,打造开发者中心城市
  13. 鸟哥的私房菜-基础篇学习-文件与目录管理-2-1
  14. rocketmq消息积压
  15. python 快速排名发包_SEO怎么快速排名?SEO快排发包技术原理是怎么实现的呀?(悬赏5元) - 搜外问答...
  16. BFS - CH2906 - 武士风度的牛
  17. 【转租】【房东直租】【次渠东里一区、高层正规两居室、次卧】
  18. 滚动轴承故障特征频率计算公式
  19. c# 计算圆锥的体积_急求用c#计算圆柱体和圆锥体的体积的代码,下面是要求:...
  20. 『与善仁』Appium基础 — 3、移动端测试环境搭建(三)之AVD模拟器安装

热门文章

  1. 虚拟机无法玩腾讯游戏该怎么办
  2. 人工智能会成为下一场的科技革命吗?
  3. 如何用EXCEL求一组数的方差…
  4. Go Micro 初探
  5. git配置-新人git配置
  6. (文末福利)如果代码莫名其妙跑起来了,就不要去动它了……吗?
  7. @Transactional注解回滚(事物)
  8. 将ip电话注册到服务器上,ip电话怎么安装设置 ip电话安装设置方法文字详解【图文】...
  9. Unbound classpath container: ‘JRE System Library’已解决
  10. React 待办事项列表案例