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

如何通过wasmtime-dotnet向WebAssembly传递函数?

解决方案

问题根源

你遇到的核心问题是:C代码编译时默认未启用WASM的Reference Types扩展,导致函数指针被编译为i32(整数类型)而非WASM标准的funcref(函数引用类型);而wasmtime-dotnet中动态创建的Function实例对应funcref,无法直接与i32类型兼容。


步骤1:修改C代码并启用Reference Types编译

首先调整C函数签名为明确的函数指针类型(避免用void*模糊类型),并在编译时开启Reference Types扩展:

修改后的C代码

__attribute__((export_name("add_func")))
void add_func(void (*callback)()) {
    // 直接将callback传递给期望函数指针的C库API
}

编译命令(WASI SDK)

添加-mreference-types参数,让编译器生成funcref类型的参数:

clang --target=wasm32-wasi -mreference-types -o module.wasm module.c

步骤2:在wasmtime-dotnet中正确传递动态函数

此时WASM模块的add_func参数类型为funcref,可以直接用Function类型传递:

using var store = new Store();
var module = Module.FromFile(store.Engine, "module.wasm");
var instance = new Instance(store, module, Array.Empty<object>());

// 创建动态回调函数
var dynamicCallback = Function.FromCallback(store, (caller, args, results) => {
    // 实现你的回调逻辑
    Console.WriteLine("动态函数被调用");
});

// 获取并调用add_func
var addFunc = instance.GetAction<Function>("add_func");
addFunc?.Invoke(dynamicCallback);

特殊场景:必须保留void*参数

如果因兼容现有C库必须使用void*,需要启用非标准的ref.as_i32扩展(需确认WASI SDK支持),但这种方式不推荐:

修改C代码

__attribute__((export_name("add_func")))
void add_func(void* func_ptr) {
    void (*callback)() = (void (*)())func_ptr;
    // 使用或传递callback
}

编译命令

添加-mref-as-i32参数:

clang --target=wasm32-wasi -mreference-types -mref-as-i32 -o module.wasm module.c

C#侧处理

需通过WASM模块内的辅助函数将funcref转换为i32,不能直接传递整数(宿主动态函数无模块内索引),这种方式复杂度高且兼容性差,优先推荐第一种方案。


内容的提问来源于stack exchange,提问作者IS4

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:45:31