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

Tho*_*her 5 javascript c++ emscripten


我在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);
Run Code Online (Sandbox Code Playgroud)

用于处理数字的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);
}
Run Code Online (Sandbox Code Playgroud)

这是按预期工作,但我想知道是否有任何机会origFunc直接从Javascript 调用以摆脱myFunc丑陋 reinterpret_cast.
当我尝试通过以下方式绑定origFunc时:

EMSCRIPTEN_BINDINGS(test) {
  function("origFunc", &origFunc, emscripten::allow_raw_pointers());
}
Run Code Online (Sandbox Code Playgroud)

...并直接调用它:

Module.origFunc(buf, size);
Run Code Online (Sandbox Code Playgroud)

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

这是emscripten的一般限制,还是存在比解决方案更"脏"的解决方案reinterpret_cast

Mic*_*mza 0

你可以使用static_cast如果你

  • 指定该函数采用 avoid *而不是 a uintptr_t

  • 不要使用EMSCRIPTEN_BINDINGS,而是使用JS->C++ 的EMSCRIPTEN_KEEPALIVE+ cwrap/ccall方式进行通信。由于某种原因,当我尝试该方法时,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;
}
Run Code Online (Sandbox Code Playgroud)

可以通过 Javascript 调用

Module.ccall('myFunc', 'number' ['number', 'number'], [buf, size]);
Run Code Online (Sandbox Code Playgroud)