gpt4 book ai didi

javascript - 在 emscripten 中的已知堆地址处创建数组

转载 作者:行者123 更新时间:2023-12-02 21:52:11 31 4
gpt4 key购买 nike

我将几 kB 的数据(生成的 PNG 文件)从 Unity3D WebGL 上下文传递到 javascript,以便用户可以在不离开 WebGL 上下文的情况下下载 PNG 文件。 Unity使用emscripten并将js嵌入为jslib。这是我第一次查看 emscripten 或在 js 中使用指针,在 emscripten 文档中找不到基础知识。

它可以工作,但我认为这是一个糟糕的实现,代码如下:

mergeInto(LibraryManager.library, {
JSDownload: function(filenamePointer, dataPointer, dataLength) {
filename = Pointer_stringify(filenamePointer);
var data = new Uint8Array(dataLength);
for (var i = 0; i < dataLength; i++) {
data[i]=HEAPU8[dataPointer+i];
}
var blob = new Blob([data], {type: 'application/octet-stream'});
if(window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, filename);
}
else{
var elem = window.document.createElement('a');
elem.href = window.URL.createObjectURL(blob);
elem.download = filename;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
}
}
});

令我困扰的是这样的单步执行数据,因为我已经有了地址和长度,所以我想在已知地址实例化“数据”数组,就像我在 C 中使用 * 和 & 一样,而不是复制它是一个字节一个字节地复制,或者如果我必须复制它,至少要一次点击而不是循环复制。我认为我最大的问题是不知道在哪里寻找文档。我通过查看 GitHub 上的随机项目发现了比这里更多的内容:https://emscripten.org/docs/api_reference/preamble.js.html

如有任何帮助,我们将不胜感激,谢谢。

最佳答案

所以你不喜欢这部分?

var data = new Uint8Array(dataLength);
for (var i = 0; i < dataLength; i++) {
data[i]=HEAPU8[dataPointer+i];
}
var blob = new Blob([data], {type: 'application/octet-stream'});

你可以把它写成一行:

var blob = new Blob([HEAPU8.subarray(dataPointer, dataPointer + dataLength)], {type: 'application/octet-stream'});

// or this

var blob = new Blob([new Uint8Array(HEAPU8.buffer, dataPointer, dataLength)], {type: 'application/octet-stream'});

它们都应该比您的原始代码快得多,并且它们都应该具有完全相同的性能。这是因为他们直接从 HEAPU8 创建一个新的 Blob,而不像原始代码那样创建重复的数组。

HEAPU8 是一个 Uint8Array,TypedArray 系列之一。关于 TypedArray 的一件非常重要的事情是,它实际上不是缓冲区/数据,而是底层 ArrayBuffer(它是 HEAPU8.buffer)对象的一个​​“ View ”,该对象保存实际数据。请参阅ArrayBufferView .

所以 HEAPU8HEAPU8.buffer ArrayBuffer 对象提供了一个接口(interface),具体来说 WebAssembly.Memory.buffer在 Emscripten 中,看起来像一个 uint8_t 数组。 Emscripten 还提供了 HEAPU16、HEAPU32、HEAPF32 等,但它们具有相同的 ArrayBuffer 和不同的 View 。

.subarray(start, end)new Uint8Array(buffer, offset, size) 的作用是创建 ArrayBuffer 对象的新“ View ”指定范围内,不复制缓冲区。因此,您的性能损失将降至最低。

关于javascript - 在 emscripten 中的已知堆地址处创建数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60106899/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com