簡體   English   中英

調用V8函數會導致訪問沖突

[英]Calling V8 function causes access violation

我有一個全局事件管理器,可讓您使用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范圍問題。 但是我不知道。

是什么原因導致訪問沖突?如何解決?

我相信這里有幾個潛在的問題。

首先,在ModuleScript::jsOn()終止后,您沒有使用持久性句柄來保存JavaScript函數。 到事件處理程序被調用時,該功能可能已消失。 考慮使callback成為持久句柄。

其次,事件處理程序需要在調用JavaScript函數之前輸入適當的V8上下文。 根據您的體系結構,還可能需要明確鎖定並輸入V8隔離。

第三(這在您的特定情況下可能不是問題),您需要管理V8隔離的壽命。 如果事件管理器在后台線程上觸發事件,則必須確保事件處理程序以某種方式防止隔離對象與另一個線程分離。 不幸的是,這是V8 API不能提供太多幫助的領域。

第四,為防止泄漏,事件處理程序應在調用函數后處置持久函數句柄。

祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM