我正在尝试获取WebAssembly缓冲区的内存地址并将其返回给Javascript,以便我可以将其内存设置为Javascript ArrayBuffer,并直接在模块内存中的相应地址处写入数组。
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个字节。
如何找出这些地址指向模块内存的位置?
答案 0 :(得分:2)
您已通过importObject.env.memory
为模块提供了内存。您只需使用提供的偏移量/地址来检查分配给C代码中buff
变量的内存:
// 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中看到更完整的示例。