【发布时间】: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>());
...
onStateUpdateCallback 和 onErrorCallback 都是 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<v8::Function>())以便获得 RAII。
标签: c++ node.js callback v8 node.js-addon