[英]Call C++ function from JavaScript asynchronously using Emscripten
我對Emscripten有一個小問題。 如何從JavaScript異步調用C ++回調?
這是我的JS代碼:
<script type="text/javascript">
function sendRequest(callback) {
setTimeout(function(){
callback["sayHi"]();
}, 100);
}
</script>
這是我的C ++代碼:
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
class MyClass {
public:
void sayHi () {
printf("Hello! \n");
};
};
EMSCRIPTEN_BINDINGS(MyClass)
{
class_<MyClass>("MyClass")
.function("sayHi", &MyClass::sayHi);
}
int main() {
val window = val::global("window");
auto myObj = MyClass();
window.call<void>("sendRequest", myObj);
return 0;
}
當我執行此代碼時,它失敗並顯示錯誤:
Uncaught BindingError: Cannot pass deleted object as a pointer of type MyClass*
我使用emcc 1.35.22並使用以下命令對其進行編譯:
~/app/emsdk_portable/emscripten/tag-1.35.22/emcc main.cpp --bind -o out.js
由於某些原因,當您致電
window.call<void>("sendRequest", myObj);
等到堆棧從上一行清除時,Emscripten / embind會刪除myObj
(如果在MyClass中添加析構函數,則可以看到此信息)。
第二個問題是,即使Emscripten / embind沒有這樣做,
auto myObj = MyClass();
在main
, myObj
是在堆棧上創建的,因此它將在main
的末尾(即異步回調之前)刪除。
圍繞這兩種方法的一種方法是在堆上創建對象,將其作為原始指針以及指向靜態回調的函數指針傳遞給Javascript。 您可以使用EM_ASM_ARGS
從C ++中調用,然后使用dynCall_*
函數從Javascript中的函數指針進行調用。
例如,C ++就像
void callback(MyClass *myObj)
{
myObj->sayHi();
}
MyClass *myObj;
int main() {
myObj = new MyClass();
EM_ASM_ARGS({
sendRequest($0, $1);
}, &callback, myObj);
// myObj is still in memory
// be sure to delete it
return 0;
}
和JavaScript
Module = {
noExitRuntime: true
};
function sendRequest(callback, myObj) {
setTimeout(function() {
Module.dynCall_vi(callback, myObj);
}, 1000);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.