如何找出WebAssembly缓冲区的地址并将其返回给Javascript?
问题描述:
我想获得WebAssembly缓冲区的内存地址并将其返回给Javascript,以便我可以将其内存作为Javascript ArrayBuffer实例化,并直接在模块内存中的适当地址写入数组。如何找出WebAssembly缓冲区的地址并将其返回给Javascript?
C代码:
#include <stdint.h>
uint8_t buff[10][100];
uint64_t addr(int buffer_index){
return (uint64_t)&buff[buffer_index];
}
我编译:
emcc project.c -Os -s WASM=1 -s SIDE_MODULE=1 -o project.wasm
的HTML:
<script>
var importObject = {
env: {
memoryBase: 0,
tableBase: 0,
setTempRet0:(x)=>{},
memory: new WebAssembly.Memory({ initial:256 }),
table: new WebAssembly.Table({ initial:0, element:'anyfunc' })
}
};
fetch('http://localhost:9000/assets/wasm/project.wasm').then(
response => response.arrayBuffer()
).then(
bytes => WebAssembly.instantiate(bytes, importObject)
).then(
results => {
let module=results.instance
let exports=module.exports
let addr=exports._addr
console.log(addr(0))
console.log(addr(1))
console.log(addr(2))
}
)
</script>
运行的结果:
project.html:21 5242880
project.html:22 5242980
project.html:23 5243080
看起来很理智,因为缓冲区有100个字节块,返回的地址相距100个字节。
如何找到这些地址指向模块内存的位置?
答
您已通过importObject.env.memory
向模块提供了内存。您只需使用提供检查分配给您的buff
变量存储在C代码的偏移量/地址:
// create a Uint8Array as a 'view' on the module linear memory
// starting at _addr(0), and with a length of 100 elements.
var buffer = new Uint8Array(importObject.env.memory.buffer, exports._addr(0), 100);
for (var i=0; i<buffer.length; i++) {
var foo = buffer[i];
// do something with foo here!
}
你可以看到my project that renders a Mandelbrot fractal一个更完整的例子。
感谢您的回答,它已经解决了我的问题。然而,不是内存,你必须看内存缓冲区,所以正确的行是:'var buffer = new Uint8Array(importObject.env.memory.buffer,exports._addr(0),100);'。我也喜欢Mandelbrot分形的项目。 – sbtpr
好点,我更新了代码! – ColinE
'(exports._addr || exports.addr)(0)' - 下划线仅由emcc添加,llvm按原样导出名称。 – Vitaly