使用Emscripten Docker镜像编译报undefined exported symbol如何解决
问题原因
- Emscripten默认开启死代码消除,未标记保留的C函数会被优化掉,不会出现在WASM导出表中,这是你不加EXPORTED_FUNCTIONS时前端调用失败的原因。
- 你配置EXPORTED_FUNCTIONS后编译报错,是两个格式问题导致的:
- EXPORTED_FUNCTIONS参数要求传入JSON数组格式,不能直接写函数名
- Emscripten默认会给C函数的符号添加下划线前缀,你直接写
wam编译器找不到对应符号
解决方法
方法1:直接修正编译命令(无需修改C代码)
修改编译命令,补全EXPORTED_FUNCTIONS的数组格式,给函数名加下划线前缀,同时可添加NO_NAME_MANGLING参数保持原函数名,避免修改前端代码:
/usr/bin/docker run --rm -v $(pwd):/src emscripten/emsdk emcc --no-entry -s EXPORTED_FUNCTIONS='["_wam"]' -s NO_NAME_MANGLING=1 wam.c
如果不添加NO_NAME_MANGLING参数,需要将前端调用代码改为instance.exports._wam()。
方法2:给C函数添加导出标记(更稳妥,避免手动维护导出列表)
修改wam.c代码,引入emscripten头文件,给需要导出的函数添加EMSCRIPTEN_KEEPALIVE宏标记,编译器会自动保留并导出该函数:
#include <emscripten.h> EMSCRIPTEN_KEEPALIVE int wam() { return 2; }
修改后编译命令可简化,无需配置EXPORTED_FUNCTIONS参数,同样可添加NO_NAME_MANGLING保持原函数名:
/usr/bin/docker run --rm -v $(pwd):/src emscripten/emsdk emcc --no-entry -s NO_NAME_MANGLING=1 wam.c
内容的提问来源于stack exchange,提问作者Adrian May
相关产品推荐
相关产品推荐

