Emscripten: C++ callback dies inside emscripten::val#call

Created on 8 Mar 2016  路  2Comments  路  Source: emscripten-core/emscripten

I'm working on product which is based on Emscripten and recently I stuck with one problem.

What I need to do:

  1. from the C++ code I want to call method of the JS object and pass callback (which is C++ object) as a parameter;
  2. when my JS method receives data from the server I want to call my C++ callback.

I wrote some demo code which represents my problem, you can find it here. The problem is that at this moment my callback is already dead and I can't call it (BindingError: Cannot pass deleted object as a pointer of type Callback*). How can I keep it alive and call asynchronously?

Also I tried to write workaround without emscripten::val#call and it works (you can see the code here) but this signature of JS method is unacceptable for our product. Another problem with workaround is that I lose context ('this' inside sendRequest points to the wrong object).

Thank you in advance!

embind wontfix

Most helpful comment

I literally just ran into a similar problem and was stumped for about two months... and then I finally found a little gem of a solution which just worked for me called clone. Applying it to your code it would look like this:

  // we call this function from C++ code
  var callbackHolder = null;
  var requestManager = {
    sendRequest: function(callback) {
      console.log('call callback synchronously');
      callback["sayHi"]();
      callbackHolder = callback.clone(); // Clone the callback so you can maintain a handle on the pointer

      setTimeout(function() {
        console.log('call callback asynchronously');
        // TODO: how to keep callback alive?
        callbackHolder["sayHi"]();
        callbackHolder.delete(); // Don't forget to delete the cloned object or you may run into memory leaks
      }, 100);
    }
  };

I didn't try it with your code specifically but doing a similar thing for my code solved my problem.

All 2 comments

I literally just ran into a similar problem and was stumped for about two months... and then I finally found a little gem of a solution which just worked for me called clone. Applying it to your code it would look like this:

  // we call this function from C++ code
  var callbackHolder = null;
  var requestManager = {
    sendRequest: function(callback) {
      console.log('call callback synchronously');
      callback["sayHi"]();
      callbackHolder = callback.clone(); // Clone the callback so you can maintain a handle on the pointer

      setTimeout(function() {
        console.log('call callback asynchronously');
        // TODO: how to keep callback alive?
        callbackHolder["sayHi"]();
        callbackHolder.delete(); // Don't forget to delete the cloned object or you may run into memory leaks
      }, 100);
    }
  };

I didn't try it with your code specifically but doing a similar thing for my code solved my problem.

This issue has been automatically marked as stale because there has been no activity in the past 2 years. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.

Was this page helpful?
0 / 5 - 0 ratings