Javascript Emscripten未捕获范围错误:源太大,多个数组 我试着运行一个4x4矩阵乘法的C++函数。两天后,它终于起作用了,但并不像预期的那样
通常,参数会反馈到函数,然后此行:Javascript Emscripten未捕获范围错误:源太大,多个数组 我试着运行一个4x4矩阵乘法的C++函数。两天后,它终于起作用了,但并不像预期的那样,javascript,c++,emscripten,asm.js,Javascript,C++,Emscripten,Asm.js,通常,参数会反馈到函数,然后此行: dataHeap2.set( new Uint8Array(data2.buffer) ); 产生错误“未捕获范围错误:源太大” 乍一看,它似乎只是一个普通的Float32Array,包含16个元素,但在查看其缓冲区大小之后,它似乎有所不同 console.log(data2.buffer.bufferLength); 结果不是预期的64字节,而是像3342345这样的巨大数字。这就是问题所在吗?我找到了一个解决方法,手动复制值(如下所示),返回值,然后问
dataHeap2.set( new Uint8Array(data2.buffer) );
产生错误“未捕获范围错误:源太大”
乍一看,它似乎只是一个普通的Float32Array,包含16个元素,但在查看其缓冲区大小之后,它似乎有所不同
console.log(data2.buffer.bufferLength);
结果不是预期的64字节,而是像3342345这样的巨大数字。这就是问题所在吗?我找到了一个解决方法,手动复制值(如下所示),返回值,然后问题就消失了。不幸的是,它使我的代码比直接在缓冲区上操作慢得多
// bad solution - which works
for(var i = 0; i < 16; i++) {
dataTarget[i] = result[i];
}
要使用数据2的头64字节,请指定偏移量和长度
dataHeap2.set( new Uint8Array(data2.buffer, data2.byteOffset, nDataBytes) );
这似乎解决了问题,但我担心。set函数只复制数据,因此不是真正的解决方案。至少比循环克隆要优雅一点(但它比“Module.HEAPU8.buffer.slice”好吗?)
另外,我讨厌创建新的Float32Array实例,因为它会降低所有速度谢谢,我已经尝试过了。获取“RangeError:Start offset太大:”实际上没有错误。my game.Asm.js中只有白色屏幕似乎需要单堆缓冲区。可能需要复制或malloc/免费管理@zakki好的,所以我认为复制到传递的targetFloat32会起作用,但是我不知道如何将这个Module.HEAPU8.buffer,this.dataPtr+144,16馈送到现有的Float32Array中,而不创建一个新的实例:new Float32Array(Module.HEAPU8.buffer,this.dataPtr+144,16)。这太慢了。类似的问题被证明是缓冲区初始化为小于所设置数据大小的值。
new Uint8Array(Module.HEAPU8.buffer, this.dataPtr, 64).set( new Uint8Array(data.buffer, data.byteOffset, 64) );
// second matrix allocate and copy to emscripten's heap
new Uint8Array(Module.HEAPU8.buffer, this.dataPtr + 72, 64).set( new Uint8Array(data2.buffer, data2.byteOffset, 64) );
// multiply first two parameters and return in the last one
this.mmul_vec4(this.dataPtr, this.dataPtr + 72, this.dataPtr + 144);
// like that it works, unfotunately copying is being made here
return new Float32Array(Module.HEAPU8.buffer.slice(this.dataPtr + 144, this.dataPtr + 208));
// with this version (if uncommented) there's just white screen(but it looks like the game is working.
//return new Float32Array(Module.HEAPU8.buffer, this.dataPtr + 144, 16);
dataHeap2.set( new Uint8Array(data2.buffer, data2.byteOffset, nDataBytes) );
matrix4multiplyBlocking = function(data, data2, dataTarget) {
//console.log(new Float32Array(data2.buffer, data2.byteOffset, 16));
// Copy data to Emscripten heap
new Uint8Array(Module.HEAPU8.buffer, this.dataPtr, 64).set( new Uint8Array(data.buffer, data.byteOffset, 64) );
// second matrix allocate and copy to emscripten's heap
new Uint8Array(Module.HEAPU8.buffer, this.dataPtr + 72, 64).set( new Uint8Array(data2.buffer, data2.byteOffset, 64) );
// multiply first two parameters and return in the last one
this.mmul_vec4(this.dataPtr, this.dataPtr + 72, this.dataPtr + 144);
// Free memory
//Module._free(this.dataPtr);
dataTarget.set(new Float32Array(Module.HEAPU8.buffer, this.dataPtr + 144, 16));
};