You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:22:17