0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

WebAssembly_Web运行CC++程序(win10)

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2022-08-14 09:44 次阅读

1. WebAssembly技术介绍

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

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

WebAssembly的中文官网: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 变体。

image-20220216140201666

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

image-20220216140016455

Emscripten的官网也有详细介绍: emscripten.org/docs/gettin…

image-20220216140034973

2. 安装Emscripten编译器

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

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

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

python环境安装看这里:

xiaolong.blog.csdn.net/article/det…

xiaolong.blog.csdn.net/article/det…

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

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

blog.csdn.net/xiaolong112…

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

image-20220216141158931

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

git clone https://github.com/emscripten-core/emsdk.git 
复制代码

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

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

image-20220216141552254

输入命令进入到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 permanently
​
Setting the following tools as active:
  node-12.18.1-64bit
  python-3.7.4-pywin32-64bit
  java-8.152-64bit
  releases-upstream-37fc7647c754ac9a28ad588c143b82286de0ef71-64bit
​
Setting 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_TestCode
​
D:\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.emscripten
​
It contains our best guesses for the important paths, which are:
​
 LLVM_ROOT    = /usr/bin
 NODE_JS     = C:\Program Files\nodejs\node.exe
 EMSCRIPTEN_ROOT = C:\Qt\emsdk\upstream\emscripten
​
Please 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/.emscripten
​
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: 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 
int main() 
{
  printf("Hello World! \n");
    printf("WebAssembly 牛逼!\n");
  return 0;
}
复制代码

(2)使用emcc编译编译

D:>cd /d D:\linux-share-dir\tmp\WebAssembly_TestCode
​
D:\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个文件。

image-20220216144752704

(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。

image-20220216145318947

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

image-20220216145352353

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

$ emrun --no_browser --port 8080
复制代码

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

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

#include 
#include 
​
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


Compile C to WebAssembly

The test result can be found in console.

复制代码

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

python -m http.server
复制代码

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

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

image-20220217175755657

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

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

image-20220217180042334

5. webassembly在线调试工具

地址:wasdk.github.io/WasmFiddle/

image-20220217103905595

6. wasm2wast工具安装

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

地址: github.com/WebAssembly…

用法示例:

wast2wasm demo.wast -o demo.wasm
​
wasm2wast 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.7
     
(7)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. 总结

image-20220216171629754
审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Web
    Web
    +关注

    关注

    2

    文章

    1263

    浏览量

    69455
  • 编译器
    +关注

    关注

    1

    文章

    1634

    浏览量

    49128
  • Win10
    +关注

    关注

    2

    文章

    710

    浏览量

    39988
收藏 人收藏

    评论

    相关推荐

    win10下无法运行STVD怎么解决?

    win10运行STVD的时候,出现这个问题,不知要怎么解决。谢谢
    发表于 04-10 06:39

    win10使用技巧有哪些 win10使用技巧分享

    win10使用技巧有哪些?近来有很多朋友问有没有win10系统的基本使用教程,大家都知道,win10增加了很多小功能,给我们带来了很多方便,如果了解这些使用技巧可以达到事半功倍的效果。下面给大家带来
    发表于 09-05 08:53

    Win10 激活工具

    win10/win8激活工具
    发表于 02-07 16:14 52次下载

    CC++编程指南

    CC++编程指南
    发表于 10-27 14:45 9次下载
    <b class='flag-5'>CC++</b>编程指南

    Win10 强制更新重启解决办法

    装了WIN10的小伙伴肯定是被WIN10很多问题给困扰了吧,尤其是软件兼容,为了找到一个WIN10版本的软件,总是要历尽千辛万苦,才能正常运行软件,打开
    的头像 发表于 09-08 11:56 1.6w次阅读

    想要安装win10系统,它对电脑的最低配置是什么

    很多朋友在自己组装电脑的时候由于预算不足,想要组装一台能够运行win10系统流畅的低配电脑,这个时候就要考虑到win10系统配置的要求了。
    的头像 发表于 03-14 14:21 9933次阅读

    win10的Proteus 8应用程序安装教程免费下载

    本文档的主要内容详细介绍的是win10的Proteus 8应用程序安装教程免费下载。
    发表于 04-26 08:00 26次下载
    <b class='flag-5'>win10</b>的Proteus 8应用<b class='flag-5'>程序</b>安装教程免费下载

    如何关闭win10的网络搜索功能

    我们知道微软在Win10中,特别加强了系统的搜索功能,但Win10的搜索的确很难称得上好用。
    的头像 发表于 12-29 15:40 3438次阅读
    如何关闭<b class='flag-5'>win10</b>的网络搜索功能

    CC Debugger win10 win7驱动及CC Debugger固件免费下载

    本文档的主要内容详细介绍的是CC Debugger win10 win7驱动 及CC Debugger固件免费下载。
    发表于 03-03 08:00 72次下载
    <b class='flag-5'>CC</b> Debugger <b class='flag-5'>win10</b> <b class='flag-5'>win</b>7驱动及<b class='flag-5'>CC</b> Debugger固件免费下载

    win10系统激活密钥key详细步骤

      Win10一年的免费升级服务已经到期,用户要使用Win10系统,就需要最新Win10密钥来激活Win10,一般激活Win10系统有两种方
    发表于 03-10 11:35 6次下载
    <b class='flag-5'>win10</b>系统激活密钥key详细步骤

    win10系统新电脑分区的详细教程

    win10操作系统是目前最新的操作系统。很多用户购买的新电脑安装的都是win10操作系统,在使用的时候发现只有一个c盘分区。于是就想了解win10系统新电脑分区怎么操作,那么今天小编就来跟大家分享一下
    的头像 发表于 05-01 17:22 1.1w次阅读
    <b class='flag-5'>win10</b>系统新电脑分区的详细教程

    win7和win10禁用数字签名的教程

    win7和win10禁用数字签名的教程
    发表于 06-10 10:12 23次下载

    PICKIT3 WIN10无法识别问题

    通过网上修改注册表的方式没有一点效果,后来发现跟系统可能有关系,换了一个新的WIN10系统就解决了解决方法:换新的win10操作系统,测试版本:win10专业版64位(10.0 19042),在
    发表于 11-16 20:36 4次下载
    PICKIT3 <b class='flag-5'>WIN10</b>无法识别问题

    关于win10驱动安装失败的解决

    关于win10驱动安装失败的解决现在win10的驱动安装是学习单片机的路上一大拦路虎,故本人找到了解决win10成功安装驱动的方法最有效的方法按win+r然后输入service.msc
    发表于 12-20 18:45 25次下载
    关于<b class='flag-5'>win10</b>驱动安装失败的解决

    win10win11哪个好用

    win10win11各有优势,具体哪个更好要根据实际的应用场景和需求来决定。 首先,从性能方面来看,Win11在单线程、多线程、渲染和3DMark运行时的流畅性都优于
    的头像 发表于 11-26 14:51 4945次阅读