2017-02-24 71 views
13

我有一个非常大的ArrayBuffer(或TypedArray)在JavaScript中,我想传递给emscriptened函数。我想传递原始字节而不会产生副本。传递JS ArrayBuffer或TypedArray到Emscripten W/O复制

如果我的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(),但这似乎并没有工作。
我错过了什么?

+0

不是'var ptr = Module._malloc(bytes);新的Uint8Array(Module.HEAPU8.buffer,ptr,字节);'好,而不是'新的Uint8Array(字节)'在JS? – zakki

+0

是的。如果缓冲区是通过'Module._malloc()'分配的,并直接传递给希望有一个'char * ptr'的asm.js函数,它不会产生副本(正如我在emscripten论坛上向我解释的那样)。稍后将发布完整答案。 –

+0

@zakki从网络读取数据或写入HTML5画布时,不能使用预先分配的缓冲区;该缓冲区由浏览器分配。 emscripten似乎没有办法直接访问本地JS对象,甚至在'EM_ASM'块中,这真的很奇怪。 – HRJ

回答

0

回答我自己。
就目前而言,没有办法允许emscriptened C/C++代码访问JS分配的内存缓冲区。

也就是说,使用C API时,通过Module._malloc()分配的缓冲区可以“通过指针”传递

Embinding将向C++类型添加额外的复制。

欲了解更多信息,请参阅this emscripten邮件列表上的线程。

+0

我想这应该是可能的使用文件系统API。 –

+0

我不熟悉它。你什么意思?另外请注意,自问题出现以来,事情可能发生了变化,特别是WASM的发布。 –

+0

我知道你可以在一个WorkerFS中加载一个文件blob,但似乎没有支持任意ArrayBuffer(在File System API中)。作为文件访问它们听起来是可行的,也许应该添加。 –