将 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 显示没有PdPd 是什么? 恕我直言“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 函数

使用 emscripten 将字符串从 C++ 传递给 JS

将文件名传递给 Emscripten 生成的 js 作为参数

将 C/C++ 套接字传递给 EM_ASM 以在 Emscripten 中用作 websocket

Emscripten malloc 和跨 JS 和 C++ 的免费

您是不是必须释放传递给 Emscripten 中导出的 C 函数的字符串?