将传递lambda函数作为回调参数

时间:2016-04-02 08:49:46

标签: javascript c++ lambda emscripten

我想创建一个计算某事的函数。完成后,它会调用回调函数。

void calculate(int param1, ..., std::function<void(void)> callback) {
    //code...
    callback();
}

使用Embind

创建函数的绑定
EMSCRIPTEN_BINDINGS(my_module) {
    function("calculate", &calculate);
}

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

UnboundTypeError: Cannot call calculate due to unbound types: NSt3__18functionIFvvEEE

2 个答案:

答案 0 :(得分:4)

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

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

对于您的示例,稍微简化界面,以便仅从JS传递回调 - &gt; C ++,C ++可能如下所示:

extern "C" {

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

}

创建回调函数指针的Javascript看起来像

var callbackPointer = Module.Runtime.addFunction(function() {
  console.log('In the callback');
});

并调用该函数,传递指针(作为&#34;数字&#34;):

Module.ccall('calculate', 'number', ['number'], [callbackPointer]);

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

em++ app.cpp -s RESERVED_FUNCTION_POINTERS=1 -o app.js

答案 1 :(得分:1)

你现在可以这样做:

void calculate(int param1, ..., emscripten::val callback) {
    callback();
}

EMSCRIPTEN_BINDINGS未更改。

回调甚至可以采用参数,只要它们是受支持/声明的类型(例如,如果您将std::vector<blah>参数传递给回调,请确保您已使用register_vector<blah>()。)< / p>