У меня есть демонстрационная скрипка онлайн на https://webassembly.studio/?f=0r9gxzb9rdq, где я использую буфер массива, который используется совместно JS и WebAssembly.
Как предлагается в этом ответе Как получить доступ к линейной памяти WebAssembly из 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 требуемую память и передать ее в виде WebAssembly.Memory, как только я узнаю, сколько нужно 64 тыс. Страниц:
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) => {...});
});
Что я не могу понять, так это точный способ доступа к буферу WebAssembly.Memory с использованием C. В Интернете полно примеров кода о том, как работает JS-сторона API, но все примеры кода, которые я когда-либо смогу найти на стороне WebAssembly написаны в WAT.