5

I’m building a node-module wrapper for a C++ library to pass logging information through Nan to JavaScript. For this a NAN_Method is available to register a callback. The callback handler has to register itself as a callback at the C++ library via vlAddLogListener(). The LoggingCallbackHandler receives a message from the library at the function dispatchEvent, a C++ function. If I receive a log, I want to call the JavaScript callback to pass the data on.

The function dispatchEvent isn’t called in a Nan-context and therefore I don’t have a scope/context and no access to v8. How is it possible to call the JavaScript callback?

The code looks like this:

NAN_METHOD(registerLoggingCallback) 
{
    v8::Isolate* isolate = info.GetIsolate();
    v8::Local<v8::Function> fun = info[0].As<v8::Function>();
    lch = new LoggingCallbackHandler(isolate, fun);
}

LoggingCallbackHandler::LoggingCallbackHandler(v8::Isolate* isolate, v8::Local<v8::Function> fun) :
    _cb(isolate, fun)
{
    vlAddLogListener(&LoggingCallbackHandler::dispatchEvent, this);
}

void VL_CALLINGCONVENTION LoggingCallbackHandler::dispatchEvent(const char* eventData, void* clientData)
{
    // here I want to process the data and call the JavaScript callback
    v8::Local<v8::Function> f = v8::Local<v8::Function>::New(Nan::GetCurrentContext()->Global()->GetIsolate(), _cb);
    Nan::MakeCallback(Nan::GetCurrentContext()->Global(), f, argc, argv);
}
1
  • 1
    Did you make it? Would be nice if you could provide your solution. Commented Oct 4, 2018 at 15:17

1 Answer 1

4

Using Nan, you should save the function value using a Nan::Callback inside your registerLoggingCallback function :

Nan::Callback cb;
cb.Reset(info[0].As<v8::Function>());

Store this Nan::Callback inside your class. Modify your dispatchEvent function to use a uv_async_t to schedule a call to your callback to be run in the main thread.

The use of uv_async_t can be simplified using a Nan::AsyncWorker but you may be better off reading the documentation for a better understanding of how that works.

When you actually want to call the callback, you can do:

v8::Local<v8::Value> arg = Nan::Null();
cb.Call(1, &arg);

You can pass more values into the callback by passing an array of v8::Local<v8::Value> as the second parameter and increasing the first parameter accordingly.

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.