簡體   English   中英

使用Emscripten從JavaScript異步調用C ++函數

[英]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();

mainmyObj是在堆棧上創建的,因此它將在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM