Reputation: 1726
How would you save a javascript supplied callback in a v8 wrapped object for future use not only in the current function call. Essentially i want to create a javascript object in C++ and when created with new Object() supply a function callback. Then use that callback throughout the c++ objects life. See example below:
The issue im having is when I try to use the Handle object in a different static function it seg faults.
In node js file:
var Object = require("./customModule");
var obj = new Object(function(){console.log("Callback called...")})
// Emit callback
obj.emitCallback();
In c++ module header
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"));
}
Upvotes: 9
Views: 6704
Reputation: 161457
You need to use v8::Persistent
instead of a standard handle. Handle
is the base class for Local
and Persistent
so by doing the cast that you are doing, you are grabbing a pointer to the v8::Function
but not doing anything that would tell V8 not to garbage-collect it.
With this in your class:
v8::Persistent<v8::Function> m_faceDetectCallback;
and assigned with
obj->m_faceDetectCallback = v8::Persistent<v8::Function>::New(args[0]);
Upvotes: 13