V8调用函数导致访问冲突(Calling V8 function causes access vio

2019-10-18 06:30发布

我有一个全球性的事件管理器,允许你用lambda表达式来听string事件名称。

// somewhere in the ModuleScript class
Event->Listen("WindowResize", [=]{
    // ...
});

现在,我要注册到从JavaScript事件了。 因此,我写了这个回调。

v8::Handle<v8::Value> ModuleScript::jsOn(const v8::Arguments& args)
{
    // get pointer to class since we're in a static method
    ModuleScript *module = (ModuleScript*)HelperScript::Unwrap(args.Data());

    // get event name we want to register to from arguments
    if(args.Length() < 1 || !args[0]->IsString())
        return v8::Undefined();
    string name = *v8::String::Utf8Value(args[0]);

    // get callback function from arguments
    if(args.Length() < 2 || !args[1]->IsFunction())
        return v8::Undefined();
    v8::Handle<v8::Function> callback =
        v8::Local<v8::Function>::Cast(args[1]->ToObject());

    // register event on global event manager
    module->Event->Listen(name, [=]{
        // create persistent handle so that function stays valid
        // maybe this doesn't work, I don't know
        v8::Persistent<v8::Function> function =
            v8::Persistent<v8::Function>::New(args.GetIsolate(), callback);
        // execute callback function
        // causes the access violation
        function->Call(function, 0, NULL);
    });

    return v8::Undefined();
}

当触发事件时,应用程序崩溃与访问冲突。 我的想法是,要么函数对象是无效的,在这个时候了,或者它是一个JavaScript作用域的问题。 但我无法弄清楚。

是什么原因导致的访问冲突,以及如何克服呢?

Answer 1:

我认为有几个潜在的问题在这里。

首先,你不使用持久句柄来保存后的JavaScript函数ModuleScript::jsOn()终止。 通过事件处理程序被调用时,该功能可能会消失。 考虑制定callback持久句柄。

其次,你的事件处理程序需要调用JavaScript函数前输入一个合适的V8环境。 根据您的架构,明确锁定并进入V8分离可能需要为好。

第三(这可能不是您的具体方案的问题),你需要管理的V8分离的寿命。 如果你的事件管理器触发的后台线程事件,你必须确保你的事件处理程序以某种方式阻止从另一个线程设置在隔离。 不幸的是,这是一个领域V8 API并没有提供太多的帮助。

四,防止泄漏,事件处理程序应该调用该函数后处置持久性功能手柄。

祝好运!



文章来源: Calling V8 function causes access violation