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.