调用V8函数导致访问冲突 [英] Calling V8 function causes access violation

查看:21
本文介绍了调用V8函数导致访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个全局事件管理器,允许您使用 lambda 来监听 string 事件名称.

I have a global event manager, allowing you to listen with lambdas to string event names.

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

现在,我也想从 JavaScript 注册事件.所以,我写了这个回调.

Now, I want to register to events from JavaScript, too. Therefore, I wrote this callback.

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 范围问题.但我想不通.

When the event is triggered, the application crashes with a access violation. My thoughts are that either the function object isn't valid at this time anymore, or it is a JavaScript scope issue. But I couldn't figure it out.

是什么导致了访问冲突以及如何克服它?

What causes the access violation and how to overcome it?

推荐答案

我相信这里有几个潜在的问题.

I believe there are several potential issues here.

首先,在 ModuleScript::jsOn() 终止后,您没有使用持久句柄来保存 JavaScript 函数.当您的事件处理程序被调用时,该函数可能已经消失了.考虑使 callback 成为持久句柄.

First, you're not using a persistent handle to hold the JavaScript function after ModuleScript::jsOn() terminates. By the time your event handler is invoked, the function might be gone. Consider making callback a persistent handle.

其次,您的事件处理程序需要在调用 JavaScript 函数之前进入适当的 V8 上下文.根据您的架构,可能还需要明确锁定和进入 V8 隔离区.

Second, your event handler needs to enter an appropriate V8 context before calling the JavaScript function. Depending on your architecture, explicitly locking and entering the V8 isolate may be required as well.

第三(在您的特定场景中这可能不是问题),您需要管理 V8 隔离的生命周期.如果您的事件管理器在后台线程上触发事件,您必须确保您的事件处理程序以某种方式防止隔离被另一个线程处理.不幸的是,这是 V8 API 没有提供太多帮助的领域.

Third (and this may not be an issue in your specific scenario), you need to manage the lifetime of the V8 isolate. If your event manager fires events on background threads, you have to make sure your event handler somehow prevents the isolate from being disposed from another thread. Unfortunately this is one area where the V8 API doesn't provide much help.

第四,为防止泄漏,您的事件处理程序应在调用函数后处理持久函数句柄.

Fourth, to prevent a leak, your event handler should dispose the persistent function handle after invoking the function.

祝你好运!

这篇关于调用V8函数导致访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆