2016-04-16 47 views
1

我想从我的异步附加函数中调用nodejs回调。我见过同步示例(here) ,我正在使用一个美妙的异步示例(here)作为起始基础。NodeJS Addon从NAN内部调用Javascript回调AsyncWorker ::执行

但是,当我尝试执行给C++ AsyncWorker子类的回调时,出现Segmentation故障。

这里是我的代码:

#include <nan.h> 
#include <functional> 
#include <iostream> 
#include <exception> 
using namespace Nan; 
using namespace v8; 
using namespace std; 

class ScriptWorker : public AsyncWorker { 
    public: 
    ScriptWorker(Callback *callback, const std::map<std::string, Callback*>) 
    : AsyncWorker(callback), script(script), cbs(cbs) {} 

    ~ScriptWorker() {} 

    void Execute() { 

     // ------------------------ 
     // Segmentation fault after 
     // ------------------------ 

     Local<Value> argv[] = { 
     New<v8::Number>(id) 
     }; 

     // ------------------------- 
     // Segmentation fault before 
     // ------------------------- 

     cbs["getUser"]->Call(1, argv); 
    } 

    private: 
    std::string script; 
    std::map<std::string, Callback*> cbs; 
}; 

NAN_METHOD(Method) { 
    Local<Object> array = info[0]->ToObject(); 
    Callback *callback = new Callback(info[1].As<Function>()); 

    // Build up callbacks passed in from javascript. 
    // Will be a dynamic loop, but for now, hard code the one getUser example. 
    std::map<std::string, Callback*> cbs; 
    cbs.insert(std::pair<std::string, Callback*>("getUser", 
    new Callback(
     array->Get(
     v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "getUser") 
    ).As<Function>() 
    ) 
)); 
    AsyncQueueWorker(new ScriptWorker(callback, cbs)); 
} 

NAN_MODULE_INIT(Init) { 
    Nan::Set(target, Nan::New<String>("hello").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(Method)).ToLocalChecked()); 
} 

NODE_MODULE(hello, Init) 

我的问题:

  1. 我不该使用楠的AsyncWorker,转而推出自己的?
  2. 如何设置执行功能调用JavaScript?

回答

4

编辑:

看到这个回购:

https://github.com/xavero/node_addon_sample

它如何与回调函数和由C土地发光事件工作的样本。

您不应该在ScriptWorker的Execute方法中调用v8/Nan函数,否则将会出现段错误。重写HandleOKCallback函数以使用JavaScript回调。

要从JavaScript调用,在C++插件:

NAN_MODULE_INIT(Init) { 
    Nan::Set(target, Nan::New("myJsFunctionName").ToLocalChecked(), 
    Nan::GetFunction(Nan::New<FunctionTemplate>(Method)).ToLocalChecked()); 
} 

NODE_MODULE(anyNameHere, Init) 

而在你的javascript:

// run "npm install bindings --save" in console first 
var addon = require('bindings')('NativeExtension'); 

addon.myJsFunctionName({ foo: "bar"}, (arg1,arg2) => console.log(`${arg1} - ${arg2}`)) 
+1

对不起,我一直在度假,但现在我回来了,准备解决这个问题。 @Xavero,我忘记在我的示例中包含NAN_MODULE_INIT和NODE_MODULE调用。他们现在在那里。我明白你在说什么,在主线程之外制作V8对象和调用。我认为我需要走老派,并使用uv_thread_create()和uv_async_t与uv_mutex_t结合,以使“自定义”(在NAN异步工作者期望的范围之外)调用。有什么想法吗? – EToreo

+0

如果你想要一个回调(执行一个C异步函数,然后是一个带有响应的javascript),正确的方法是使用AsyncQueueWorker + ScriptWorker。相信我。 现在,如果你想从C地发出一个事件,那么你需要使用uv lib – Xavero

+0

上周我在一个项目中做了这个...让我用一个简单的例子设置一个要点或东西。给我几个小时。 – Xavero