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);
}
Using
Nan, you should save the function value using aNan::Callbackinside yourregisterLoggingCallbackfunction :Store this
Nan::Callbackinside your class. Modify yourdispatchEventfunction to use auv_async_tto schedule a call to your callback to be run in the main thread.The use of
uv_async_tcan be simplified using aNan::AsyncWorkerbut 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:
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.