为什么我的Wasm函数无法接收JavaScript对象参数?

慕容春晖 阅读 34

我在用WebAssembly导入C函数时遇到了问题。导出的函数需要接收一个包含x/y坐标的对象参数,但调用时总报错说类型不匹配。

尝试过把对象转成JSON字符串再传入,但Wasm端解析时字符串长度超过预期导致溢出。现在直接传数字参数又感觉代码耦合太严重,有没有更好的方法处理复杂参数?

导出的C函数定义是这样的:


extern void process_point(double x, double y);

在JS里这样调用会报错:


const point = {x: 100, y: 200};
Module.process_point(point); // Uncaught TypeError: expected number, got object

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
爱学习的小汐
这个问题的本质在于WebAssembly目前只支持非常基础的类型,比如数字、数组等,它没法直接理解JavaScript的对象结构。所以你传入一个对象时,Wasm不知道怎么处理,就会报类型不匹配的错误。

更好的写法是利用Wasm的线性内存来传递复杂数据。具体来说,可以在Wasm模块中分配一块内存,用来存储你的对象数据,然后把这块内存的指针传给Wasm函数。下面是一个可行的实现方式:

首先在C代码里调整一下函数定义,改成接收指针的形式:

// C代码
#include

extern void process_point(const double* point);


然后在JavaScript端,可以用Wasm模块提供的内存操作工具来写入对象数据:

// JavaScript代码
function callProcessPoint(instance, x, y) {
const buffer = new Float64Array(instance.exports.memory.buffer, 0, 2);
buffer[0] = x;
buffer[1] = y;
instance.exports.process_point(0); // 0是buffer的起始偏移量
}


调用的时候可以这样写:

const point = {x: 100, y: 200};
callProcessPoint(Module, point.x, point.y);


这样做的好处是避免了手动序列化和解析字符串的麻烦,同时性能也更高。不过要注意的是,Wasm的内存管理需要你自己小心处理,别忘了清理或者复用内存,否则可能会导致内存泄漏。

如果你觉得每次手动写这些调用太啰嗦,可以封装成一个通用的工具函数,专门用来处理类似的需求。这种写法不仅优雅,还能减少重复代码,维护起来也方便多了。
点赞 1
2026-02-19 22:09
闲人银银
WebAssembly不能直接传JS对象,得用指针在内存里搞。试试看把对象写进Wasm内存:

const point = {x: 100, y: 200};
const ptr = Module._malloc(16);
Module.HEAPF64[ptr >> 3] = point.x;
Module.HEAPF64[(ptr + 8) >> 3] = point.y;
Module.process_point(ptr);
Module._free(ptr);


C那边改成接收double*,别用两个单独的double参数。
点赞 3
2026-02-13 07:00