Passing Pointer/Ref to C++ Object Method to Javascript Callback

494 views
Skip to first unread message

primesoftw...@gmail.com

unread,
Jun 21, 2016, 9:00:14 PM6/21/16
to emscripten-discuss
I would like to instantiate an object in C++ and have a Javascript onload function callback to one of the instantiated objects methods. The plan would be to call the Javascript code from C++ and then have the Javascript callback to the object function. What is the best way to do this? I've been looking at EMBind, but I don't want to instantiate in Javascript. Thanks!

Juha Järvi

unread,
Jun 22, 2016, 10:01:47 AM6/22/16
to emscripten-discuss
This would be pretty easy to do with nbind if you first call some C++ function with pointers to all JavaScript the functions you need to call. Note that the following code currently only works when compiled with Emscripten.

Your C++ code could for example have a main init function that gets called from JavaScript and after that, you can have most of the action happen in C++ if you want. In this example, init receives one JavaScript function it can then call at any time. init also instantiates a C++ object and passes that to the JavaScript function.

#include <string>
#include <iostream>

#include "nbind/nbind.h"

struct Foobar {
  void frob(std::string data) {
    std::cout << data << "\n";
  }
};

void init(nbind::cbFunction &jsFunction) {
  Foobar *foo = new Foobar();

  jsFunction(foo);
}

#include "nbind/nbind.h"

NBIND_CLASS(Foobar) {
  method(frob);
}

NBIND_GLOBAL() {
  function(init);
}

Now let's see the JavaScript side, which calls the C++ init function and can give it pointers to JavaScript functions. The example function here takes a C++ object, and calls the frob method after some delay, passing it a string.

var nbind = require('nbind');
var lib = nbind.init().lib;

function something(foo) {
  setTimeout(function() { foo.frob('Hello, World!'); }, 1000);
}

lib.init(something);

Hopefully this would fit your needs. The same code should also work in a future 0.3 version of nbind when compiled using GCC, Clang or Visual Studio 2015 into a native Node.js addon. Currently however passing pointers to objects constructed in C++ to JavaScript is only supported when compiling with Emscripten.

PSN

unread,
Jun 22, 2016, 8:50:32 PM6/22/16
to emscripten-discuss
Hmm....I think I need to stick with Emscripten. The basic usage of what I am trying to do is make an XMLHttpRequest by calling Javascript code from C++ and then having the Javascript callback to the C++ code. I know there is a wget function in Emscripten, but you can't set any headers with it. Since I'm making a REST API client that is quite crippling. I've been doing some reading and I think lambdas might help out here, but there aren't any full examples. I saw Chad's discussion here, but I'm still not clear on it.

My initial thought was to instantiate an "HTTPClient" class in C++ and create several lambda functions (with capture by value) inside the calling member method that could be passed as callbacks. So far I cannot get that to compile.

I do like the ease of use with nbind though. I see you have a "nbind::cbOutput" type over there. Sounds like what I am trying to do. How much does nbind increase the size of the output JS though?
Reply all
Reply to author
Forward
0 new messages