返回「计算机、信息技术与工程」

Emscripten-C++到WebAssembly编译机制

Emscripten C++到WebAssembly编译机制 1. 它是什么

更多
Markdown 结构化数据
本文目录 6 个章节

Emscripten-C++到WebAssembly编译机制

1. 它是什么

Emscripten 是基于 LLVM 的 C/C++→WebAssembly 交叉编译器。 常用入口命令:

  • emcc – C 源文件 → WebAssembly
  • em++ – C++ 源文件 → WebAssembly

2. 产物长什么样

一次编译通常会生成两份文件:

  1. xxx.wasm — 二进制指令,真正运行在浏览器 / Node 的模块
  2. 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