嵌入传递 lambda 函数作为回调参数

Ite*_*tor 5 javascript c++ lambda emscripten

我想创建一个函数来计算一些东西。完成后,它会调用回调函数。

void calculate(int param1, ..., std::function<void(void)> callback) {
    //code...
    callback();
}
Run Code Online (Sandbox Code Playgroud)

函数的绑定是使用以下命令创建的Embind

EMSCRIPTEN_BINDINGS(my_module) {
    function("calculate", &calculate);
}
Run Code Online (Sandbox Code Playgroud)

但如果我尝试打电话,Module.calculate(0, ..., function(){/*...*/})我会收到此错误:

UnboundTypeError: Cannot call calculate due to unbound types: NSt3__18functionIFvvEEE
Run Code Online (Sandbox Code Playgroud)

Mic*_*mza 5

我不确定这是否是唯一的方法,但要从 Js -> C++ 传递回调,我必须

  • 不是 use std::function,而是原始函数指针
  • 用于Runtime.addFunction获取 Javascript 函数的 C++ 函数指针,并将其传递到 C++ 世界,而不是尝试直接传递 Javascript 函数。
  • 不是使用EMBIND,而是cwrap/ ccallAPI

对于您的示例,稍微简化接口,以便仅从 JS -> C++ 传递回调,C++ 可能如下所示:

extern "C" {

EMSCRIPTEN_KEEPALIVE
void calculate(void (*callback)()) {
  callback();
}

}
Run Code Online (Sandbox Code Playgroud)

创建回调函数指针的 Javascript 可能如下所示

var callbackPointer = Module.Runtime.addFunction(function() {
  console.log('In the callback');
});
Run Code Online (Sandbox Code Playgroud)

并调用该函数,传递指针(作为“数字”):

Module.ccall('calculate', 'number', ['number'], [callbackPointer]);
Run Code Online (Sandbox Code Playgroud)

然后编译,确保为函数指针保留空间:

em++ app.cpp -s RESERVED_FUNCTION_POINTERS=1 -o app.js
Run Code Online (Sandbox Code Playgroud)