WebAssembly.Instance 实例化后为什么无法访问导出的函数?
我用 Emscripten 编译了一个简单的 C 函数,想在浏览器里调用。加载 .wasm 文件后,通过 WebAssembly.instantiate() 创建了 Instance,但打印 instance.exports 时发现里面是空的,明明 C 代码里用了 EMSCRIPTEN_KEEPALIVE 标记了函数。
我试过检查模块是否加载成功,也确认了编译命令加了 -s EXPORTED_FUNCTIONS,但还是拿不到导出的函数。是不是实例化方式有问题?我的 JS 代码大概是这样:
fetch('test.wasm')
.then(res => res.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(result => {
console.log(result.instance.exports); // 输出 {}
});
Emscripten 编译出来的 wasm,导出的函数名会带个下划线前缀。你在 C 里写的
int add(int a, int b),在 JS 里导出后叫_add,不是add。所以你先试试这样访问:
如果还是 undefined,那问题在编译参数这块。
你的编译命令大概长这样对吧:
注意几个点:
1. 导出函数名单独用引号包住不行,得用单引号包双引号这种嵌套写法,或者用逗号分隔
2.
_main必须加上去,不然 Emscripten 生成的入口点没导出来,整个模块可能不正常3. 如果你想导出所有函数,可以加
-s EXPORT_ALL=1还有一种情况是,你用的是新版 Emscripten(2.0+),它的默认行为有变化。如果上面的方法不行,试试在编译时加上:
--no-entry是告诉编译器没有 main 函数,适合只导出单独函数的情况。你先把编译命令贴出来,我看看具体是哪儿的问题。