如何在浏览器中运行Emscripten编译代码生成的WASM文件
Emscripten环境下调用WASM函数实现方案
你示例中读取本地文件调用外部WASM的场景可以通过Emscripten提供的JS/C++桥接能力实现,具体步骤如下:
核心实现逻辑
你需要通过EM_JS宏在C++代码中嵌入JS逻辑,读取虚拟文件系统中的WASM二进制内容,实例化后调用对应导出函数,完整代码示例如下:
#include <emscripten.h> #include <fstream> #include <iostream> #include <string> // 实现execute_wasm_func:参数为WASM文件路径,返回值为WASM函数执行结果 EM_JS(int, execute_wasm_func, (const char* file_path), { // 从Emscripten虚拟文件系统读取WASM二进制内容 const wasm_file_content = Module.FS.readFile(UTF8ToString(file_path)); // 实例化WASM模块,如需传递导入函数可在第二个参数传入importObject const wasm_instance = new WebAssembly.Instance(new WebAssembly.Module(wasm_file_content)); // 调用WASM导出的目标函数,此处假设目标函数名为target_func,无入参返回int类型 return wasm_instance.exports.target_func(); }); int main(){ // 此处需保证写入的user_post_wasm_file为合法的WASM二进制内容 // 通常是将用户上传的WASM文件先通过JS写入Emscripten虚拟文件系统 std::ofstream file("user_post_wasm_file", std::ios::binary); // 省略写入WASM二进制内容的逻辑 file.close(); auto r = execute_wasm_func("user_post_wasm_file"); std::cout << r + 1 << std::endl; return 0; }
编译参数
使用如下命令编译代码:emcc main.cpp -o index.html -s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_RUNTIME_METHODS=['FS']
注意事项
- 如果要调用的WASM函数有入参,需要注意C++类型和WASM类型对齐,传递指针时需要在Emscripten堆上申请内存
- 大体积WASM建议使用异步实例化,需要同步开启Emscripten的
ASYNCIFY特性避免阻塞浏览器主线程 - 实例化WASM时如果目标WASM依赖导入的环境函数/内存,需要在实例化时传入对应的importObject配置
内容的提问来源于stack exchange,提问作者fuyutsubaki
相关产品推荐
相关产品推荐

