如何用Emscripten将C前置声明转为WebAssembly导入函数?
问题描述
我有一段用于演示思路的简化C代码:
#include <stdint.h> #include <string.h> #include <stdio.h> #ifdef __EMSCRIPTEN__ #include <emscripten.h> #endif void some_function(int32_t some_argument); void EMSCRIPTEN_KEEPALIVE my_function(int32_t arg1, int32_t arg2) { some_function(arg1); some_function(arg2); }
我希望将这段代码编译为WebAssembly,让some_function的前置声明转为WebAssembly导入,由宿主在运行时提供实现。但使用命令emcc --no-entry -O3 -o mywasm.wasm mycode.c编译时,出现错误:wasm-ld: error: undefined symbol: some_function。我知道这是因为该函数没有实现,但这正是我的需求。我查阅了emscripten.h的文档,未找到将函数设为必填WebAssembly导入的相关配置,请问通过Emscripten能否实现该需求?
解决方案
可以实现,你需要通过链接器参数或代码属性标记,告诉工具链将some_function视为外部导入函数,具体有两种常用方式:
方式一:添加链接器参数
在编译命令中加入-Wl,--undefined=some_function,明确告诉wasm-ld不要因为some_function未定义而报错,而是将其作为WebAssembly的导入项处理。完整编译命令如下:
emcc --no-entry -O3 -Wl,--undefined=some_function -o mywasm.wasm mycode.c
方式二:代码中添加导入属性
在C代码里给some_function的声明添加属性标记,明确指定它是从外部模块导入的函数。修改后的代码如下:
#include <stdint.h> #include <string.h> #include <stdio.h> #ifdef __EMSCRIPTEN__ #include <emscripten.h> #endif // 标记为从env模块导入的some_function函数 void __attribute__((import_module("env"), import_name("some_function"))) some_function(int32_t some_argument); void EMSCRIPTEN_KEEPALIVE my_function(int32_t arg1, int32_t arg2) { some_function(arg1); some_function(arg2); }
修改后直接使用原编译命令即可完成编译:
emcc --no-entry -O3 -o mywasm.wasm mycode.c
补充说明
- 若需要自定义导入模块名,可修改
import_module的参数(比如改为import_module("host_utils")),宿主在提供函数实现时需对应这个模块名。 - 编译完成后,可使用
wasm-objdump工具验证导入项是否生效:
wasm-objdump -x mywasm.wasm | grep some_function
内容的提问来源于stack exchange,提问作者Michael Stum
相关产品推荐
相关产品推荐

