将 JS 数字数组传递给 emscripten C++ 而无需 reinterpret_cast
Posted
技术标签:
【中文标题】将 JS 数字数组传递给 emscripten C++ 而无需 reinterpret_cast【英文标题】:Passing JS number array to emscripten C++ without reinterpret_cast 【发布时间】:2015-07-14 09:55:45 【问题描述】:我在 JS 中有大量数组,我想将它们传递给 C++ 进行处理。 恕我直言,最有效的方法是让 JS 直接写入 C++ 堆并在直接调用中将指针作为参数传递,例如:
var size = 4096,
BPE = Float64Array.BYTES_PER_ELEMENT,
buf = Module._malloc(size * BPE),
numbers = Module.HEAPF64.subarray(buf / BPE, buf / BPE + size),
i;
// Populate the array and process the numbers:
parseResult(result, numbers);
Module.myFunc(buf, size);
处理数字的 C++ 函数如下所示:
void origFunc(double *buf, unsigned int size)
// process the data ...
void myFunc(uintptr_t bufAddr, unsigned int size)
origFunc(reinterpret_cast<double*>(bufAddr), size);
按预期工作,但我想知道是否有机会直接从 javascript 调用 origFunc
以摆脱 myFunc
和 丑 reinterpret_cast
。
当我尝试通过以下方式绑定 origFunc 时:
EMSCRIPTEN_BINDINGS(test)
function("origFunc", &origFunc, emscripten::allow_raw_pointers());
...直接调用它:
Module.origFunc(buf, size);
我收到错误:Uncaught UnboundTypeError: Cannot call origFunc due to unbound types: Pd
这是对 emscripten 的一般限制,还是有比 reinterpret_cast
解决方法“不那么脏”的解决方案?
【问题讨论】:
我不太了解emscripten,但看起来您在将分配的数组buf / BPE
传递给函数之前修改了它的位置。我怀疑需要buf
。并且函数的大小参数可能应该只是size * BPE
。
错误涉及Pd
类型,但代码sn-ps 显示没有Pd
,Pd
是什么?
恕我直言“Pd”来自 emscripten 并保留为“Pointer double”
buf计算正确,_malloc()返回一个字节地址,但是HEAPF64.subArray()对每个double(F64)元素分割成8个字节
好的,我不确定我能不能帮忙(过去的 cmets)。
【参考方案1】:
如果您愿意,您可以使用static_cast
指定该函数采用void *
而不是uintptr_t
;
不要使用EMSCRIPTEN_BINDINGS
,而是使用EMSCRIPTEN_KEEPALIVE
+ cwrap
/ ccall
JS->C++ 的通信方式。由于某种原因,EMSCRIPTEN_BINDINGS
方式在我尝试时导致了getTypeName is not defined
异常。
所以函数看起来像:
extern "C" int EMSCRIPTEN_KEEPALIVE myFunc(void *bufAddr, unsigned int size)
origFunc(static_cast<double *>(bufAddr), size);
return 0;
可以通过 Javascript 调用
Module.ccall('myFunc', 'number' ['number', 'number'], [buf, size]);
【讨论】:
以上是关于将 JS 数字数组传递给 emscripten C++ 而无需 reinterpret_cast的主要内容,如果未能解决你的问题,请参考以下文章
使用 emscripten 将字符串从 C++ 传递给 JS
将文件名传递给 Emscripten 生成的 js 作为参数
将 C/C++ 套接字传递给 EM_ASM 以在 Emscripten 中用作 websocket