【问题标题】:EXC_BAD_ACCESS: When calling Nan::CallbackEXC_BAD_ACCESS:调用 Nan::Callback 时
【发布时间】:2019-02-12 13:43:55
【问题描述】:

我正在编写一个 Node.js c++ 插件,它需要从 C++ 到 Javascript 的频繁回调。

构造函数需要两个函数,一个成功回调和一个错误回调。

...
// assuming info[0] and info[1] are functions with ->IsFunction()
MyClass* myClass = new MyClass();
myClass->Wrap(info.Holder());
myClass->onStateUpdateCallback = new Nan::Callback(info[0].As<v8::Function>());
myClass->onErrorCallback = new Nan::Callback(info[1].As<v8::Function>());
...

onStateUpdateCallbackonErrorCallback 都是 MyClass 类的私有属性,定义如下:

...
Nan::Callback* onStateUpdateCallback;
Nan::Callback* onErrorCallback;
...

现在,当我从另一个函数调用 onStateUpdateCallback 时,它第一次工作,但第二次通过抛出 EXC_BAD_ACCESS 失败(通过 lldb 调试时)。

这就是我调用回调的方式(注意:该函数从在不同线程中执行调用的外部库中调用,第一次在主线程中,第二次在线程#13中,这可能会导致问题!):

...
const int argc = 4;
// The arguments should be numbers and strings, but I simplified it to null...
v8::Local<v8::Value> argv[argc] = {
    Nan::Null(),
    Nan::Null(),
    Nan::Null(),
    Nan::Null()
};
onStateUpdateCallback->Call(argc, argv);
...

我假设函数或范围已被 Javascript 垃圾收集,但我不知道如何防止这种行为,有什么想法吗?

谢谢。

【问题讨论】:

  • 您发布的代码部分之外的内容可能是罪魁祸首。 Nan::Callbacks 是持久的(不允许被包装函数的 GC)。
  • 旁注:强烈建议定义 class MyClass { Nan::Callback onStateUpdateCallback; } 并使用 myClass.onStateUpdateCallback.Reset(info[0].As&lt;v8::Function&gt;()) 以便获得 RAII。

标签: c++ node.js callback v8 node.js-addon


【解决方案1】:

正如我所想,不同的线程存在问题。

我使用Nan::AsyncProgressWorker 解决了线程问题。

【讨论】:

  • 你在哪里添加 Nan::AsyncProgressWorker?
  • @bmacnaughton 我基本上采用了绑定类并将其移至继承自Nan::AsyncProgressWorker 的自己的类中。绑定类初始化并启动绑定类。
猜你喜欢
  • 2017-04-03
  • 2011-02-25
  • 1970-01-01
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多