WebAssembly与C++实战:从入门到精通

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

WebAssembly与C++简介



现代网页开发不断寻求提升性能的方法。WebAssembly (Wasm) 是一种低层级的二进制指令格式,能在浏览器中以接近原生的速度执行。结合C++这一最快、最强大的编程语言之一,Wasm开辟了新天地:从高性能游戏和模拟,到直接在浏览器中运行的复杂数据处理算法。



本文将带您从基础走向实践:讲解如何将C++代码编译为WebAssembly,在浏览器中运行,并优化以获得最佳性能。



1. 工具集与环境配置



将C++编译为WebAssembly的主要工具是Emscripten编译器套件。它将LLVM字节码转换为Wasm,并自动生成加载模块所需的JavaScript胶水代码。



安装Emscripten

推荐的安装方式是通过包管理器emsdk:



# 克隆仓库git clone https://github.com/emscripten-core/emsdk.gitcd emsdk

# 安装并激活最新版本./emsdk install latest./emsdk activate latest

# 添加环境变量(shell变量)source ./emsdk_env.sh


安装后,您将获得emcc(C编译器)和em++(C++编译器)命令,它们是Clang的封装。



2. 将C++编译为WebAssembly



来看一个最简单的例子。创建文件hello.cpp:



#include <emscripten/emscripten.h>

// 可从JavaScript调用的函数extern "C" { int EMSCRIPTEN_KEEPALIVE add(int a, int b) { return a + b; }}


关键元素是宏EMSCRIPTEN_KEEPALIVE。它防止优化器删除该函数,并使其成为可导出的。



编译我们的代码:



em++ hello.cpp -o hello.html -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -O3


参数说明:

  • -o hello.html — 创建一个包含运行示例的HTML文件。
  • -s WASM=1 — 明确指定生成Wasm(默认已启用)。
  • -s EXPORTED_FUNCTIONS='["_add"]' — 导出的函数列表(带前缀_)。
  • -O3 — 高级优化。


结果将生成三个文件:hello.html、hello.js(胶水代码)和hello.wasm。



3. 与JavaScript交互



编译后,我们可以从JavaScript调用C++函数。以下是加载模块的最小代码:



<!DOCTYPE html><html><head>    <script>        var Module = {};        Module.onRuntimeInitialized = function() {            // 现在可以访问add函数            var result = Module._add(5, 7);            console.log("结果: " + result); // 12        };    </script>    <script src="hello.js"></script></head><body></body></html>


关键点:

  • Module.onRuntimeInitialized — 在Wasm模块加载完成后触发的事件。
  • JS中的函数名带有前缀_(例如_add)。
  • 传递复杂数据结构(字符串、数组)时,需使用Module._malloc和指针。


传递字符串

返回问候语的函数示例:



// C++代码extern "C" {    const char* EMSCRIPTEN_KEEPALIVE greet(const char* name) {        static std::string msg = "Hello, " + std::string(name) + "!";        return msg.c_str();    }}


在JavaS

博客

书籍推荐