emcc命令使用范例,cpp编译成wasm在html中使用
发布于 作者:苏南大叔 来源:程序如此灵动~
Emscripten是WebAssembly的编译器,它可以将C/C++代码编译成WebAssembly,然后通过JavaScript调用。emcc命令就是其中最常用的的命令。本文以一个demo.cpp作为引子,演示emcc编译命令的主要功能。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10,emcc@4.0.4。
emcc 命令安装
本文的正确使用前提,是已经安装好了Emscripten。参考文章:
可以在命令行下面,试试执行下面的命令。如果有输出,则证明环境安装正确。
emcc --version
测试:容器方案
本文生成结果的测试,需要使用html文件调用wasm文件,所以存在着跨域的问题。双击html文件打开浏览器,会报错。所以,请自行准备容器运行测试。比如nginx/apache等。或者简单的使用php或python(推荐)或node或rust,启动一个自带容器。
【推荐】最简单的方案是python。其它传统的方案,都需要做设置,或写代码,或修改mime映射,略显复杂。容器启动命令:
python -m http.server 8080起源:demo.cpp
demo.cpp文件,提供了三个导出函数,分别是:add()、greeting()、greeting_alert()。代码如下:
#include <emscripten.h>
#include <string>
extern "C" {
EMSCRIPTEN_KEEPALIVE
int add(int a, int b) {
return a + b;
}
EMSCRIPTEN_KEEPALIVE
const char* greeting() {
return "Hello from WebAssembly!";
}
EMSCRIPTEN_KEEPALIVE
void greeting_alert() {
emscripten_run_script("alert('欢迎使用 WebAssembly!')");
}
}剩下的js文件和.wasm文件,以及调用的demo.html文件,都是通过emcc命令对这个cpp文件进行处理而得到的。

编译项目
emcc命令,
- 如果
-o是个html的话,则会生成wasm、js和html文件。 - 如果
-o是个js的话,则会生成wasm、js文件。
官方推荐命令
生成HTML测试模板,官方推荐的命令是这样的:
emcc demo.cpp -o index.html然而,通过官方命令生成的index.html,代码太复杂了,不符合快速测试的要求。中间还放了个大大的啥用也没有的canvas,可能它的需求设计里面,都是编译游戏到wasm的吧。其实,苏南大叔这边的测试目的,仅仅是为了隐藏一些js函数的逻辑,起到加密的目的。
可以输出全局变量Module来查看可以使用的函数。

本文范例编译
下面的命令和模版,都是vscode自带的copilot推荐的。
emcc demo.cpp -o demo.js -s EXPORTED_FUNCTIONS="['_add', '_greeting','_greeting_alert']" -s EXPORTED_RUNTIME_METHODS="['UTF8ToString']"
配套html:
<button onclick="callAdd()">Add</button>
<button onclick="callGreeting()">Greeting</button>
<button onclick="callGreetingAlert()">Greeting Alert</button>
<script src="demo.js"></script>
<script>
function callAdd() {
var result = Module._add(5, 3);
console.log("Result of add: " + result);
}
function callGreeting() {
var greeting = Module.UTF8ToString(Module._greeting());
console.log(greeting);
}
function callGreetingAlert() {
Module._greeting_alert();
}
</script>可能存在的问题
这里提一个在测试wasm的可能比较常见的问题,就是函数返回输出字符串的问题。在好几个不同的测试环境下,wasm该输出的字符串,都变成了数字,很奇怪吧?
比如,使用下面的命令输出的demo.js文件:
emcc -Oz --closure 1 -s ENVIRONMENT=web -s FILESYSTEM=0 demo.cpp -o demo.js
所以,是编译命令的参数问题,注意调试修改。
结语
本文主要以介绍emcc命令的使用方式为主,通过一个cpp文件衍生出对应的js和wasm文件,并成功通过html文件进行调用。
更多苏南大叔的wasm文件相关经验文章,请参考: