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));
};