本文目录 6 个章节
Emscripten-C++到WebAssembly编译机制
1. 它是什么
Emscripten 是基于 LLVM 的 C/C++→WebAssembly 交叉编译器。 常用入口命令:
emcc– C 源文件 → WebAssemblyem++– C++ 源文件 → WebAssembly
2. 产物长什么样
一次编译通常会生成两份文件:
xxx.wasm— 二进制指令,真正运行在浏览器 / Node 的模块xxx.js— 运行时与胶水代码,负责加载 WASM、补充系统调用、导出接口
用 -o out.js 就会同时写出 out.wasm。
3. 运行时的三种组织方式
| 模式 | 触发方式 | 用途 |
|---|---|---|
| 单 JS 文件(默认) | 不额外设置 | 最易上手;out.js 自动拉取 out.wasm |
| 模块化输出 | -sMODULARIZE=1 -sEXPORT_ES6=1 |
把运行时包装成 ES6 Module / UMD,便于与打包工具集成 |
| 纯 Wasm “独立式” | -sSTANDALONE_WASM(曾用 -sWASM=2) |
让 .wasm 拥有完整入口表,只需极简 JS 引导即可;适合非 JS 宿主 |
4. 双向调用:让 C 和 JS 互相干活
- JS → C
cwrap/ccall在运行时直接调用导出的 C 函数。
- C → JS
把 JS 函数挂到
Module或通过EM_JS/emscripten_run_script暴露。怎样让符号“被看见”
编译时列入
-sEXPORTED_FUNCTIONS="['_foo','_bar']"或在函数上加
EMSCRIPTEN_KEEPALIVE
若想要 C++ 与 JS 保持类与实例语义,可使用 Embind。
9. 调试与安全辅助
-g4—— 生成完整 source-map;浏览器 DevTools 能单步到 C++。-sSAFE_HEAP=1—— 越界/非法 free 检测,运行时会断点并打印栈。-sASSERTIONS=2—— 开启更多运行时断言。EM_LOG=1—— 让printf直接写进浏览器控制台。
速记
编译:
emcc hello.c -O2 -o hello.js调用:Module.ccall('add', 'number', ['number','number'], [1,2])调试:-g4 -sSAFE_HEAP=1体积:-Oz --closure 1+ Brotli/Gzip 互调:EMSCRIPTEN_KEEPALIVE/cwrap/Embind