Passing JS function to Emscripten-generated code

前端 未结 5 1525
自闭症患者
自闭症患者 2020-12-29 06:13

I have a piece of C++ code converted to JavaScript via Emscripten. I would like the converted C++ code to call back to the JavaScript code that calls it. Something like:

5条回答
  •  轮回少年
    2020-12-29 07:18

    Here's what I have gathered from several posts and by looking at Emscripten bundled code:

    In C++:

    #include 
    #include 
    
    extern "C" {
      void registerCallback(void(*back)(const char*));
      void triggerCallback(char* message); // for invoking it from JS, just for this example
    }
    
    // global
    std::function gCallback;
    
    void registerCallback(void(*back)(const char*)){
        gCallback = back;
    }
    
    void triggerCallback(char* message){
      if (gCallback) {
        gCallback(message);
      } else {
        std::cerr << "Cannot pass '"<< message <<"' to undefined callback\n";
      }
    }
    

    An important thing, which was missing in other posts, is to compile C++ with RESERVED_FUNCTION_POINTERS=... flag, e.g.:

    em++ -std=c++11 -s RESERVED_FUNCTION_POINTERS=20 source.cpp -s EXPORTED_FUNCTIONS="['_registerCallback','_triggerCallback']" -o try.html
    

    After loading try.html into a browser, you can execute the following JS code in its console:

    // Register a callback function
    function callback(text){ alert("In JS: "+Pointer_stringify(text)); }
    var cb = Runtime.addFunction(callback);
    _registerCallback(cb);
    
    // Invoke it with some "C string"
    var jsStr = "XOXOXO";
    var cStr = allocate(intArrayFromString(jsStr), 'i8', ALLOC_NORMAL)
    _triggerCallback(cStr);
    
    // Free Emscripten heap and release the function pointer
    _free(cStr);
    Runtime.removeFunction(cb);
    

    You should see an alert with "In JS: XOXOXO".

提交回复
热议问题