我们希望从MFC dll (Visual Studio 2015)中显示一些浏览器窗口。不幸的是,一旦我们卸载CEF,它就崩溃了。我们发现了非常相似的问题,但从来没有答案。
为了更好地了解这个问题,我们将所有CEF内容移动到另一个dll (cefwrapper)中。这些是我们基本上要做的主要步骤:
1. LoadLibrary(cefwrapper.dll)
2. Inside cefwrapper.dll
a. CefString(&settings.browser_subprocess_path) = "cefsimple.exe"
b. CefInitialize(args, settings, this, NULL)
c. window_info.SetAsChild(hwnd, rect);
d. browser_ = CefBrowserHost::CreateBrowserSync(window_info, browser_client_.get(), url, browser_settings, request_context);
e. ::SetParent(browser_->GetHost()->GetWindowHandle(), NULL); // Prevent getting a CLOSE Message
f. CloseBrowser();
g. Waiting until OnBeforeClose was called for all browsers.
h. CefShutdown();
i. (all sub-processes (cefsimple.exe) are gone by now)
3. FreeLibrary --> CrashCallStack
libcef.dll!sandbox::BrokerServicesBase::~BrokerServicesBase() Line 135 C++
libcef.dll!sandbox::SingletonBase<sandbox::BrokerServicesBase>::OnExit() Line 63 C++
libcef.dll!_execute_onexit_table::__l2::<lambda>() Line 206 C++
libcef.dll!__crt_seh_guarded_call<int>::operator()<<lambda_7777bce6b2f8c936911f934f8298dc43>,int <lambda>(void) & __ptr64,<lambda_3883c3dff614d5e0c5f61bb1ac94921c> >(__acrt_lock_and_call::__l2::<lambda_7777bce6b2f8c936911f934f8298dc43> && setup, _execute_onexit_table::__l2::int <lambda>(void) & action, __acrt_lock_and_call::__l2::<lambda_3883c3dff614d5e0c5f61bb1ac94921c> && cleanup) Line 204 C++
libcef.dll!_execute_onexit_table(_onexit_table_t * table) Line 231 C++
libcef.dll!common_exit::__l2::<lambda>() Line 230 C++
libcef.dll!__crt_seh_guarded_call<void>::operator()<<lambda_d80eeec6fff315bfe5c115232f3240e3>,void <lambda>(void) & __ptr64,<lambda_2358e3775559c9db80273638284d5e45> >(__acrt_lock_and_call::__l2::<lambda_d80eeec6fff315bfe5c115232f3240e3> && setup, common_exit::__l2::void <lambda>(void) & action, __acrt_lock_and_call::__l2::<lambda_2358e3775559c9db80273638284d5e45> && cleanup) Line 224 C++
libcef.dll!common_exit(const int return_code, const _crt_exit_cleanup_mode cleanup_mode, const _crt_exit_return_mode return_mode) Line 278 C++不调用FreeLibrary会将问题推迟到应用程序退出的时候。
我们使用的是cef_binary_73.1.12+gee4b49f+chromium-73.0.3683.75_windows64
作为替代方案,我们通过CreateProcess启动cefsimple.exe,并将hwnd传递给该进程。不幸的是,一段时间后,浏览器窗口冻结。
发布于 2019-08-17 01:00:09
永远不要为CEF DLL调用FreeLibrary。
Chromium有许多全局对象(单例、实用程序线程),这些对象应该在应用程序结束之前一直处于活动状态。这样做是为了更快地终止应用程序:全局对象和单例不会被删除,线程不会被终止,在进程终止时没有人会担心它。
当你调用FreeLibrary时,你就破坏了这个架构。从CEF启动的线程保持活动状态,但释放了DLL内存。这样你就会崩溃。
要修复它,只需不执行步骤3。
https://stackoverflow.com/questions/55648885
复制相似问题