1

I do not have much knowledge about javascript. I have written in C++ a shared library that does certain things in a daemon thread. I needed this to be invoked from javascript. By using SWIG I've successfully able to generate a wrapper and compile my code along with it into .node module using node-gyp (wrote binding.gyp for it too). Now i can drop to node prompt and do something like:

> var a = require("./module_name")
> a.SomeCppFunction("SomeString")

and wonderfully invoke the cpp functions, start a detached thread there and return the control back to javascript. However I want to notify the javascript from the detached cpp thread about stuffs. I tried registering javascript functions by collecting function() {} signature types in void(*fp)() etc., to call them back later from c++, but that didn't work. Is there anyway to be able to achieve this ie., register javascript functions (or something else) as callback in the cpp code ?

4
  • This may help stackoverflow.com/questions/17076978/… Commented Feb 13, 2015 at 19:00
  • Possible duplicate of Calling callback from node.js native code Commented Apr 2, 2017 at 22:01
  • Does this answer your question? Calling javascript function from C++ Addon Commented Sep 27, 2022 at 14:01
  • @EzequielGarcia Thanks for you suggestion but I asked this almost 8 years back :) and haven't dealt with this tech stack for a long time now. So I don't have much idea about what I wanted anymore. If you feel your links sufficiently answers the question, feel free to close it. Otherwise I don't know what SO expects in these scenarios as I don't have much time to try and remember. Maybe post a question and answer yourself and close this as a duplicate? Commented Sep 27, 2022 at 14:20

1 Answer 1

0

You can use a combination of SWIG and Napi. An existing repo which does this is available here, with a blog here. But I'll sum up the process here.

Create your class to use in SWIG, which has a thread running in the threadMain method :

#include <Thread.H>

class Test : public ThreadedMethod {

  void *threadMain(void);

public:
  Test();

  void setFnPointer(const char* s);
};

Now in the Napi code, you will generate your thread safe function like so :

Napi::ThreadSafeFunction tsfn; ///< The node api's threadsafe function

Napi::Value Start( const Napi::CallbackInfo& info ){
  Napi::Env env = info.Env();
  // Create a ThreadSafeFunction
  tsfn = Napi::ThreadSafeFunction::New(env,
    info[0].As<Napi::Function>(),  // JavaScript function to call
    "Resource Name", 0,1);

  // return the tsfn as a pointer in a string
  char addr[24];
  sprintf(addr,"%p",&tsfn);
  return Napi::String::New(env, addr);
}

// some small code to call NODE_API_MODULE here, check the file NapiCode.C in the repo

You compile the SWIG code to one module and the Napi code down to a different module and you pass the thread safe funciton pointer from one to the other like so :

var libNapiNodejs = require('../swig/.libs/libNapiNodejs');
let fp = libNapiNodejs.start(function () {
    console.log("JavaScript callback called with arguments", Array.from(arguments));
}, 5);


// SWIG get our C++ and thread running
var libSwigCNodejs = require('../swig/.libs/libSwigCNodejs');
let test = new libSwigCNodejs.Test;

test.setFnPointer(fp); // tell swig the callback function pointer to execute
test.run(); // run the C++ thread in the SWIG module

You will see that the C++ thread calls the javascript function. This is what the C++ thread looks like in SWIG :

Napi::ThreadSafeFunction *tsfn; ///< The node api's threadsafe function
void *Test::threadMain(void){
  printf("C++ Thread enter %s\n",__func__);
  auto callback = []( Napi::Env env, Napi::Function jsCallback, int* value ) {

    jsCallback.Call( {Napi::Number::New( env, *value )} );
  };

  for (int i=0; i<10; i++){
    sleep(1);
    if (*tsfn) {
      printf("calling tsfn->BlockingCall\n");
      napi_status status = tsfn->BlockingCall( &i, callback );
      if ( status != napi_ok ) // Handle error
        break;
    }
  }
  tsfn->Release();
  printf("C++ Thread exit %s\n",__func__);
  return NULL;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.