在v8和Node.js中保存函数callback

你将如何将一个JavaScript提供的callback保存在一个v8包装的对象中,以便将来不仅在当前的函数调用中使用。 基本上我想在C ++中创build一个JavaScript对象,当用新的Object()提供一个函数callback。 然后在整个c ++对象的生活中使用该callback。 看下面的例子:

我所遇到的问题是,当我试图在一个不同的静态函数中使用句柄对象时,它会导致错误。

在节点js文件中:

var Object = require("./customModule"); var obj = new Object(function(){console.log("Callback called...")}) // Emit callback obj.emitCallback(); 

在c + +模块头

 class Object : public node::ObjectWrap { public: static void Init(v8::Handle<v8::Object> target); Object(); protected: v8::Handle<v8::Function> m_faceDetectCallback; static v8::Handle<v8::Value> New(const v8::Arguments& args); static v8::Handle<v8::Value> onEmitCallback(const v8::Arguments& args); } v8::Handle<v8::Value> Object::New(const v8::Arguments& args) { HandleScope scope; Object* obj = new Object(); obj->Wrap(args.This()); obj->m_faceDetectCallback = Handle<Function>::Cast(args[0]); //obj->m_faceDetectCallback = v8::Persistent<Function>::Cast(args[0]); // Works fine here. const unsigned argc = 1; Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) }; obj->m_faceDetectCallback->Call(Context::GetCurrent()->Global(), argc, argv); return args.This(); } static v8::Handle<v8::Value> Object::onEmitCallback(const v8::Arguments& args){ HandleScope scope; Object* obj = ObjectWrap::Unwrap<Object>(args.This()); const unsigned argc = 1; Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) }; //!! Segfaults here if(obj->m_faceDetectCallback->IsCallable()){ //obj->m_faceDetectCallback->Call(Context::GetCurrent()->Global(), argc, argv); } return scope.Close(v8::String::New("Start called")); } 

你需要使用v8::Persistent而不是标准句柄。 HandleLocalPersistent的基类,所以通过执行你正在做的强制转换,你可以抓取一个指向v8::Function的指针,但是不会做任何事情来告诉V8不要垃圾回收。

有了这个在你的课堂上:

 v8::Persistent<v8::Function> m_faceDetectCallback; 

并分配给

 obj->m_faceDetectCallback = v8::Persistent<v8::Function>::New(args[0]);