首页 > 解决方案 > 如何在 JS 中创建 WebAssembly.Memory,然后在 C 中访问它?

问题描述

我在https://webassembly.studio/?f=0r9gxzb9rdq有一个在线演示小提琴,我正在使用在 JS 和 WebAssembly 之间共享的数组缓冲区。

正如this answer How to access WebAssembly linear memory from C/C++中所建议的那样,我将它声明为我正在读写的全局数组,以及一个返回起始地址的辅助函数:

const SIZE = 6 * 1000 * 1000;
int array[SIZE]

WASM_EXPORT
int* getStartByteOffset() {
  return &array[0];
}

然后,在 JS-land 中,一旦我加载了 wasm 文件并获取了模块实例:

const SIZE = 6 * canvas.width * canvas.height;
const heap = instance.exports.memory.buffer;
const offset = instance.exports.getStartByteOffset()
const arrayView = new Int32Array(heap, offset, SIZE)

这行得通,现在 JS 和 WebAssembly 可以访问这个数组了。但这不是我想要的方式。我事先不知道所需的数组大小(画布可能是任何大小),所以我愚蠢地预先分配了一个足够大的数组以容纳 1000x1000 像素(每个像素需要六个 32 位宽的整数)。

我想要做的是在 JS 中计算所需的内存,并在知道我需要多少 64k 页面后将其作为 WebAssembly.Memory 传递:

  fetch('../out/main.wasm').then(response => response.arrayBuffer())
    .then((bytes) => {
      WebAssembly.instantiate(bytes, {
        env: {
          memoryBase: 0,
          memory: new WebAssembly.Memory({
            initial: 1 + ((6 * 4 * canvas.width * canvas.height) >> 16)
          })
        }
      }).then((wasm) => {...});
    });

我想不通的是使用 C 访问 WebAssembly.Memory 缓冲区的精确方法。互联网上充斥着关于 API 的 JS 端如何工作的代码示例,但我可以在WebAssembly 端是用 WAT 编写的。

标签: javascriptwebassembly

解决方案


推荐阅读