将 JS 数字数组传递给 emscripten C++而不reinterpret_cast

Passing JS number array to emscripten C++ without reinterpret_cast

本文关键字:而不 C++ reinterpret cast emscripten 数字 JS 数组      更新时间:2023-10-16


我在 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);

我收到错误:
未捕获的未绑定类型错误:由于未绑定类型,无法调用 origFunc:Pd

这是对 emscripten 的一般限制,还是有比reinterpret_cast解决方法"不那么脏"的解决方案?

您可以使用

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]);