【问题标题】:Passing a JS ArrayBuffer or TypedArray to Emscripten w/o Copying将 JS ArrayBuffer 或 TypedArray 传递给 Emscripten,无需复制
【发布时间】:2017-07-15 01:28:37
【问题描述】:

我在 JavaScript 中有一个非常大的 ArrayBuffer(或 TypedArray),我想将它传递给一个 emscriptened 函数。我想传递原始字节而不产生副本。

如果我的 C/C++ 函数采用 std::string,如下所示:

void processBuffer(std::string const& buffer)

我可以获取数据,但是 IIUC,转换为 std::string 会产生缓冲区的副本。

有没有办法在没有副本的情况下传递原始缓冲区?
我的访问权限是严格只读的。

我试过了:

void processBuffer(const char* str, size_t size);

在EMSCRIPTEN_BINDINGS 中设置allow_raw_pointers(),但这似乎不起作用。
我错过了什么?

【问题讨论】:

  • 不是var ptr = Module._malloc(bytes); new Uint8Array(Module.HEAPU8.buffer, ptr, bytes);好,而不是JS中的new Uint8Array(bytes)?
  • 是的。如果缓冲区是通过Module._malloc() 分配的,并直接传递给期望char* ptr 的asm.js 函数,则不会产生副本(正如在emscripten 论坛上向我解释的那样)。稍后将发布完整答案。
  • @zakki 从网络读取数据或写入 HTML5 画布时,不能使用预先分配的缓冲区;缓冲区由浏览器分配。 emscripten 似乎没有办法直接访问原生 JS 对象,即使在 EM_ASM 块内也是如此,这真的很奇怪。

标签: javascript c++ emscripten arraybuffer typedarray


【解决方案1】:

回答自己。
按照目前的情况,没有办法允许授权的 C/C++ 代码访问 JS 分配的内存缓冲区。

话虽如此,通过Module._malloc() 分配的缓冲区可以在使用 C API 时“通过指针”传递。

Embinding 会将额外的复制添加到 C++ 类型中。

有关详细信息,请参阅 emscripten 邮件列表上的 this 线程。

【讨论】:

  • 我很想通过使用文件系统 API 来实现这一点。
  • 我不熟悉。你的意思是?另请注意,自从提出并撰写此内容后,事情可能已经发生了变化,尤其是 WASM 的发布。
  • 我知道您可以在 WorkerFS 中加载文件 blob,但似乎不支持任意 ArrayBuffer(在文件系统 API 中)。将它们作为文件访问听起来可行,也许应该添加。
猜你喜欢
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
  • 2011-10-23
  • 2019-08-22
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多