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 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With