简体   繁体   中英

Passing JS number array to emscripten C++ without reinterpret_cast


I have large number arrays in JS which I want to pass to C++ for processing. IMHO the most efficient way is to let JS write directly to the C++ heap and pass a pointer as argument within a direct call, like:

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

The C++ functions to process the numbers look like:

void origFunc(double *buf, unsigned int size) {
  // process the data ...
}
void myFunc(uintptr_t bufAddr, unsigned int size) {
  origFunc(reinterpret_cast<double*>(bufAddr), size);
}

That works as expected but I wonder if there is any chance to call the origFunc directly from Javascript to get rid of myFunc and the ugly reinterpret_cast .
When I tried to bind origFunc via:

EMSCRIPTEN_BINDINGS(test) {
  function("origFunc", &origFunc, emscripten::allow_raw_pointers());
}

... and call it directly:

Module.origFunc(buf, size);

I get the error:
Uncaught UnboundTypeError: Cannot call origFunc due to unbound types: Pd

Is this a general restriction of emscripten or is there a "less dirty" solutions than the reinterpret_cast work around?

You can use a static_cast if you

  • specify that function takes a void * rather than a uintptr_t ;

  • don't use EMSCRIPTEN_BINDINGS , but use the EMSCRIPTEN_KEEPALIVE + cwrap / ccall way of communicating JS->C++ . For some reason, the EMSCRIPTEN_BINDINGS way resulted in a getTypeName is not defined exception when I tried it.

So the function looks like:

extern "C" int EMSCRIPTEN_KEEPALIVE myFunc(void *bufAddr, unsigned int size) {
  origFunc(static_cast<double *>(bufAddr), size);
  return 0;
}

which can be called from Javascript by

Module.ccall('myFunc', 'number' ['number', 'number'], [buf, size]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM