NodeJS Addon从NAN AsyncWorker::Execute内部调用Javascript回调

NodeJS Addon calling Javascript callback from inside NAN AsyncWorker::Execute

本文关键字:内部 调用 Javascript 回调 Execute NodeJS NAN AsyncWorker Addon      更新时间:2023-10-16

我想从异步插件函数中调用nodejs回调。我看到了同步示例(此处)我使用了一个很棒的异步示例(这里)作为起点。

但是,当我尝试执行一个给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. 我应该不使用Nan的AsyncWorker,而是自己滚动吗
  2. 如何设置Execute函数以调用Javascript

编辑:

参见此回购:

https://github.com/xavero/node_addon_sample

它有一个关于如何使用回调函数和从C land发出事件的示例。

您不应该在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}`))