墨香阁
| 分享生活的点滴

C++代码编译为 WebAssembly

2025年01月09日 01:05:39
7 views
2 min read
嵌入式
C++代码编译为 WebAssembly

C++代码编译为 WebAssembly

准备工作

  • 安装 Emscripten SDK
  • 准备好 C++代码
  1. 安装 Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source./emsdk_env.sh
  1. 进入 c++代码所在目录

  2. 编译 C++代码

3.1. 对 c++代码进行改造`在默认的情况下,编译之后只有 main 函数会保存,其他函数不会保存,如果需要保存其他函数,需要在 c++代码中添加以下代码

#include <emscripten.h>
extern "C" {
EMSCRIPTEN_KEEPALIVE
void function1();
void function2();
}

这样编译之后,function1 会保存下来,function2 不会保存下来。

3.2. 编译

3.2.1 一般的编译命令如下:

emcc main.cpp -s WASM=1 -o  main.html

3.2. 如果有多个源文件,可以用下面的命令:

emcc main.cpp file1.cpp file2.cpp -s WASM=1 -o main.html

3.3. 如果需要在 js 调用的时候传入参数,可以用下面的命令:

emcc main.cpp -o main.html -s WASM=1 -s EXTRA_EXPORTED_RUNTIME_METHODS=["getValue", "setValue"] -s "EXPORTED_FUNCTIONS=['_malloc','_free']"

3.4. 如果在编译之后使用报错Uncaught RuntimeError: memory access out of bounds,可能是内存分配不足导致的,可以用下面的命令:

emcc main.cpp -o main.html -s WASM=1 -s INITIAL_MEMORY=1024mb -s TOTAL_STACK=67108864 -s ALLOW_MEMORY_GROWTH=1

4.编译完成后,会在当前目录生成 main.html 文件,用浏览器打开即可运行。

4.1. 如果需要在 js 调用的时候传入参数,可以在 js 代码中使用Module.getValue()Module.setValue()方法。

4.2. 在 js 中有两种方式可以调用 wasm 代码: 方法一只能使用 number 类型

js
// 方式 1: const result = Module.ccall('add', 'number', ['number', 'number'], [1, 2]); console.log(result); // 方式 2: // 先创建内存 var size_of_struct0_T = 8 + 200 _ 8 + 200 _ 8; // 8 是 struct0 的头部大小,200 是数组大小 // 分配内存 var map = Module._malloc(size_of_struct0_T) // 填充 Lat 和 Lon 数据 coordinates.forEach((coord, i) => { Module.setValue(map + i _ 8, coord.Lat, 'double') // Lat[i] Module.setValue(map + 200 _ 8 + i _ 8, coord.Lon, 'double') // Lon[i] }) Module.setValue(map + 200 _ 8 + 200 * 8 + 4, 4, 'double') const data = Module._CoverMapObsPlan(map, pyg, obs, struct3_ptr, wpCnt, wp, wpLen, wpArea, wpTime, wpYaw, Err) // 解析结果,要看 c++文件怎么写的 // 释放内存 Module._free(map)

如果对C++代码熟悉的话,可以比较快的上手编译为wasm。如果对内存分配不熟悉,比较会比较慢。

© 2025 . 保留所有权利.

原始文章发表于 2025年01月09日 01:05:39

发表留言

全部留言 (0)

暂无留言,成为第一个留言的人吧!