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

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

问题描述

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

  //在ModuleScript类的某处
Event-> Listen(WindowResize,[=] {
// ...
});

现在,我也想注册JavaScript事件。因此,我编写了这个回调函数。

  v8 :: Handle< v8 :: Value> ModuleScript :: jsOn(const v8 :: Arguments& args)
{
//获取指向类的指针,因为我们处于静态方法
ModuleScript * module =(ModuleScript *)HelperScript: :展开(args.Data());

//获取我们想要从参数中注册的事件名称
if(args.Length()< 1 ||!args [0] - > IsString())
return v8 :: Undefined();
string name = * v8 :: String :: Utf8Value(args [0]);

//从参数获得回调函数
if(args.Length()< 2 ||!args [1] - > IsFunction())
return v8: :未定义();
v8 :: Handle< v8 :: Function> callback =
v8 :: Local< v8 :: Function> :: Cast(args [1] - > ToObject());

//在全局事件管理器中注册事件
module->事件 - >监听(名称,[=] {
//创建持久句柄,以使函数保持有效
//也许这不起作用,我不知道
v8 :: Persistent< v8 :: Function> function =
v8 :: Persistent< v8 :: Function> :: New(args.GetIsolate(),callback);
//执行回调函数
//导致访问冲突
函数 - >调用(函数,0,NULL);
});

return v8 :: Undefined();
}

当事件被触发时,应用程序会因访问冲突而崩溃。我的想法是,这个函数对象现在不再有效,或者它是一个JavaScript范围问题。但我无法弄清楚。



什么原因导致访问违规以及如何克服它?

解决方案

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

首先,您没有使用持久化句柄来保存 ModuleScript :: jsOn()终止。当你的事件处理程序被调用时,函数可能会消失。考虑让回调一个持久句柄。

其次,你的事件处理程序需要在调用JavaScript功能。根据您的体系结构,明确锁定和进入V8隔离区也是必需的。第三(这可能不是您的特定情况中的问题),您需要管理V8隔离器的使用寿命。如果您的事件管理器在后台线程上触发事件,则必须确保您的事件处理程序以某种方式防止隔离区被从另一个线程中抛弃。不幸的是,这是V8 API不提供太多帮助的一个领域。第四,为了防止泄漏,你的事件处理程序应该在调用功能。



祝你好运!


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

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

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();
}

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.

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.

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.

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.

Good luck!

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

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