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

5


我有许多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++处理数字的函数如下:
```cpp ```
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: 由于未绑定类型,无法调用origFunc:Pd

这是emscripten的一般限制吗?还是有比reinterpret_cast解决方法更好的“不那么脏”的解决方案?

我不太了解emscripten,但看起来你在将分配的数组buf / BPE传递到函数之前修改了其位置。我怀疑应该是buf。而且可能函数的大小参数应该只是size * BPE - Niall
错误提到了类型Pd,但是代码片段中没有Pd,那么Pd是什么? - Niall
在我看来,“Pd”来自emscripten,代表“指针双精度”。 - Thomas Fischer
"buf" 的计算是正确的,"_malloc()" 返回一个字节地址,但 "HEAPF64.subArray()" 对于每个 double (F64) 元素分割成 8 个字节。 - Thomas Fischer
好的,我不确定我能帮忙(超过之前的评论)。 - Niall
1个回答

0

如果您需要指定函数使用 void * 而不是 uintptr_t,可以使用 static_cast

  • 如果您不使用 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]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接