【问题标题】:Saving a function callback in v8 and Node.js在 v8 和 Node.js 中保存函数回调
【发布时间】:2012-10-15 01:04:44
【问题描述】:

您将如何将 javascript 提供的回调保存在 v8 包装对象中以供将来使用,而不仅仅是在当前函数调用中。本质上,我想在 C++ 中创建一个 javascript 对象,并在使用 new Object() 创建时提供一个函数回调。然后在整个 c++ 对象生命周期中使用该回调。请参阅下面的示例:

我遇到的问题是,当我尝试在不同的静态函数中使用 Handle 对象时,它会出现错误。

在节点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"));
}

【问题讨论】:

    标签: javascript node.js v8


    【解决方案1】:

    您需要使用v8::Persistent 而不是标准句柄。 HandleLocalPersistent 的基类,所以通过执行你正在做的转换,你抓住了一个指向 v8::Function 的指针,但没有做任何告诉 V8 不要垃圾收集它的事情。

    在你的课堂上有这个:

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

    并分配给

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

    【讨论】:

    • 哇,这给我带来了很大的麻烦!非常感谢:)
    • 现在的V8版本好像需要specify copyable traits来获取持久化句柄。
    • 然后你会如何调用这个函数?我不知道在_faceDetectCallback->调用第一个参数中要输入什么
    • 我使用 v8::Handle<:object> obj = v8::Context::GetCurrent()->Global() 作为第一个参数,它工作得很好。第一个参数实际上表示在执行函数的js代码时用什么替换'this'。
    • 如何在v8 14.x版本中实现?
    猜你喜欢
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 2012-11-29
    • 2016-07-19
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多