5

我正在为 C++ 库构建一个节点模块包装器,以将日志信息通过Nan传递给 JavaScript。为此,NAN_Method 可用于注册回调。回调处理程序必须通过在 C++ 库中将自己注册为回调vlAddLogListener()。在LoggingCallbackHandlerfunction 处接收来自库的消息dispatchEvent,一个 C++ 函数。如果我收到日志,我想调用 JavaScript 回调来传递数据。

该函数dispatchEvent不在 Nan 上下文中调用,因此我没有范围/上下文,也无法访问 v8。如何调用 JavaScript 回调?

代码如下所示:

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);
}
4

1 回答 1

3

使用Nan,您应该使用函数Nan::Callback内部的a 保存函数值registerLoggingCallback

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

将其存储Nan::Callback在您的班级中。修改您的dispatchEvent函数以使用 auv_async_t来安排对回调的调用以在主线程中运行。

可以使用uv_async_ta 来简化使用,Nan::AsyncWorker但您最好阅读文档以更好地了解其工作原理。

当您真正想要调用回调时,您可以执行以下操作:

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

您可以通过将数组v8::Local<v8::Value>作为第二个参数并相应地增加第一个参数来将更多值传递给回调。

于 2017-08-07T17:52:31.723 回答