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

Go调用Rust编译的WASM函数返回多值时参数错误如何解决

问题根因

你遇到的got 2 expected 3 arguments报错,本质是Rust extern "C" ABI和WASM原生多值返回的适配问题:
当Rust的extern "C"函数返回非基础类型的复合值(比如你这里的(*mut u8, i32)元组)时,默认的C调用约定不会直接使用WASM原生多值返回特性,而是会自动添加一个隐式的输出指针参数作为函数的第一个入参,用来存储返回的复合值,所以原本2个入参的函数就变成了需要3个入参,你调用时只传了2个,就触发了参数数量不匹配的报错。

解决方案

方案1:强制Rust使用WASM原生多值返回(推荐)

你需要调整Rust侧的声明和编译参数,同时修正Go侧的配置加载逻辑:

  1. 先修改Rust代码,引入wasm-bindgen依赖指定原生多值返回规则:
# Cargo.toml 新增依赖
[dependencies]
wasm-bindgen = "0.2"
// Rust 函数代码修改
use wasm_bindgen::prelude::*;

#[no_mangle]
#[wasm_bindgen]
pub extern "C" fn echo(ptr: *mut u8, length: usize) -> (*mut u8, i32) {
    // 原有逻辑不变
    let newptr = get_ptr(); 
    let newlength = get_length();
    (newptr, newlength)
}
  1. 编译时添加多值返回特性的编译参数:
RUSTFLAGS="-C target-feature=+multivalue" cargo wasi build
  1. 修正Go侧的Engine初始化逻辑,把你设置的多值返回配置传给Engine(你之前的代码只创建了配置但没有关联到Engine,配置并未生效):
// 修正后的Go侧初始化代码
config := wasmtime.NewConfig()
config.SetWasmMultiValue(true)
// 必须把配置传入Engine构造方法
engine := wasmtime.NewEngineWithConfig(config)
store := wasmtime.NewStore(engine)
linker := wasmtime.NewLinker(store)
// 后续调用逻辑不变
result, err := server.funcs["echo"].Call(server.ptr, int32(len(recivedBytes)))
check(err)
res := result.([]wasmtime.Val)
// 直接按索引取返回值即可
ptr := res[0].Int32()
newLength := res[1].Int32()

方案2:适配Rust默认C ABI的隐式参数规则

如果你不想引入wasm-bindgen,也可以直接适配默认的隐式参数逻辑:
Go侧调用时提前在WASM内存中申请一块足够存储返回元组的空间(两个i32共8字节),把这块空间的指针作为第一个入参传给echo函数,后续再跟上原本的两个入参,调用完成后从你申请的内存空间里读取返回的指针和长度即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:48:01