如何存储对函数的引用,以便稍后可以在节点.js C++插件模块中回调它

How do I store a reference to a function so I can call it back later in a node.js C++ addon module?

本文关键字:节点 js C++ 回调 模块 插件 存储 何存储 引用 函数      更新时间:2023-10-16

这是我用C++编写并使用node-gyp构建的node.js插件模块。当存储函数时,我正在尝试存储指向该函数的指针,以便以后可以使用它

当我稍后尝试调用它时,尽管在调用函数中出现分段错误。如果我检查两个函数中的指针(使用 cout),让我感到困惑的是它们是相同的值。

所以我猜测调用两个函数之间调用上下文的变化变化,或者我不明白我指的是什么。

所有(嗯)指针都非常感谢我在这里的问题......

#include <node.h>
#include <v8.h>
using namespace v8;
v8::Persistent<v8::Function> callbackFunction;
 Handle<Value> StoreFunction(const Arguments& args) {
    HandleScope scope;
    callbackFunction = *Local<Function>::Cast(args[0]);
    return scope.Close(Undefined());
}
Handle<Value> InvokeFunction(const Arguments& args) {
    HandleScope scope;
    Local<Value> argv[1] = { String::New("Callback from InvokeFunction")};
    callbackFunction->Call(Context::GetCurrent()->Global(), 1, argv);
    return scope.Close(Undefined());
}
void init(Handle<Object> target) {
  NODE_SET_METHOD(target, "StoreFunction", StoreFunction);
  NODE_SET_METHOD(target, "InvokeFunction", InvokeFunction);
}
NODE_MODULE(someaddonmodule, init);

当然还有一些叫js...

var myaddon = require('../build/Release/someaddonmodule');
myaddon.StoreFunction(function(data){   
    console.log("Called back: "+data);
});
myaddon.InvokeFunction();   //causes a segmentation fault

答案是因为我们不再用Java编程了。我创建的指针指向本地句柄,而不是函数。持有对此的"引用"不足以阻止 V8 垃圾收集在范围关闭时销毁它。

为了解决这个问题,需要向 V8 发出一个显式请求,以留出一些内存来保存像这样完成的功能:

Persistent< Function > percy;
Local<Function> callbackFunction = Local<Function>::Cast(args[0]);
percy = Persistent<Function>::New(callbackFunction);

如果任何对 V8 内部结构有更好了解的人知道的比这更多,我仍然非常想听听你的解释:)