目前,Webassembly 只支持少数参数类型,即固定大小的整数和浮点数。这意味着我只能从接受和返回数值的 C/Rust 模块中定义和导出函数。
但是,根据Mozilla开发人员网络,我可以从主机Javascript操作模块的内存:
由 JavaScript 或 WebAssembly 代码创建的 [M]emory 可以从 JavaScript 和 WebAssembly 访问和可变。
这听起来很有希望 - 它表明我可以将内存的一部分指定为字节缓冲区,在其中跨越语言障碍来回传输更复杂的数据。我的模块中的函数可以接受和返回指针(指针本身是i32
,固定大小的整数),从而在当前约束范围内工作。
不幸的是,目前尚不清楚我应该如何管理这段记忆。如果我需要将数据从 JS 传递到 Wasm 进程,我需要直接写入内存对象,但不知道内存中的哪些区域是空闲的。
什么是最安全的策略?我是否应该导出一对malloc
和free
样式的函数,为 JS 提供一种在调用 Wasm 之前请求内存的方法?还是有既定的最佳实践?
我认为最简单的方法是使用Emscripten,并使用其内置的malloc/free。然后导出一个函数,该函数在C++中分配通过该malloc/free请求的内存,并返回指针。这样 JavaScript 就可以调用 WebAssembly 来获取尚未使用的可用内存区域。
我在这个答案中详细介绍了如何将字符串共享到/来自 JS/wasm,其中包含上述一些内容的详细信息。
请注意,WebAssembly 中的指针并不是一个真正的东西。C++只是将它们映射到从 0 开始的内存。因此,当您为 ArrayBuffer 编制索引时,您只需要来自C++的指针,不需要额外的映射。