WebAssembly Instance导出函数调用时参数类型报错怎么办?

长孙佼佼 阅读 60

最近在用WebAssembly的Instance对象调用导出的add函数,传入两个数字直接报错,提示“Uncaught (in promise) CompileError: Expected f32, got number ‘5’”。代码明明写的是(i32, i32)返回i32,但实例化时模块明明导出的也是i32加法,这是哪里出问题了?

试过把参数转成Int32Array包装还是不行,是不是Instance的导入导出类型哪里配置错了?看浏览器开发者工具里模块导出列表显示确实有add函数,但就是参数类型检查不过…

我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
梓萱🍀
这个问题我也踩过坑。官方文档里说WebAssembly的类型检查确实很严格,但是JS调用WASM时类型会自动转换的。你这报错f32说明编译器把函数签名识别错了,很可能.wat或.wasm文件里写的是f32但JS代码里认为是i32。

检查这几个地方:
1. 确认.wat文件里函数签名确实是(i32, i32)->i32,不是(i32, i32)->f32
2. 用wasm2wat反编译看看实际生成的wasm函数签名
3. 实例化的时候检查下importObject有没有冲突的类型声明

给你个正确调用的代码示例:
const result = instance.exports.add(
new WebAssembly.RuntimeError('i32', 5),
new WebAssembly.RuntimeError('i32', 3)
);


如果还不行,可能是编译器优化搞乱了ABI。我之前用emscripten就遇到过,加个-s STRICT=1编译选项强制类型检查就好了。

另外别用Int32Array包装,wasm的i32和js的number会自动转换的,包装反而会出问题。
点赞
2026-03-07 17:09
Des.丹丹
WebAssembly默认用f32/f64,传number会被当成浮点数处理。省事的话直接用wasm-bindgen或者assemblyscript写接口,类型绑定自动搞定。非要手动搞就用Module.instance.exports.add(new Int32Array([5])[0], new Int32Array([10])[0])这种笨办法,麻烦死了。

正确姿势是用TypedArray视图,比如:
const memory = new WebAssembly.Memory({ initial: 1 });
const buffer = new Uint8Array(memory.buffer);
const i32View = new Int32Array(buffer);

i32View[0] = 5;
i32View[1] = 10;

const result = instance.exports.add(i32View[0], i32View[1]);
console.log(result); // 正确结果


懒人推荐直接用工具链,手写太累了。
点赞 25
2026-01-29 13:24