Cef5 -- 嵌入应用程序退出崩溃的问题

Cef是一个封装好的基于webkit的浏览器控件,以接口的方式封装。所以一般与现有应用程序集成,作为应用程序的一部分嵌入进去,比较常见的就是Win32项目、MFC项目。

这篇主要讲Cef集成到项目中,应用退出时崩溃的问题。

查了好多资料,cef退出一般有两件事必须做。第一,结束当前消息循环,第二,cefshutdown。

经过验证,win32项目一般不存在这个问题(很多blog的正常套路不会出问题),一般就是下面熟悉的套路

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPTSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	// Enable High-DPI support on Windows 7 or newer.
	CefEnableHighDPISupport();

	CefMainArgs main_args(hInstance);

	void* sandbox_info = NULL;

#if defined(CEF_USE_SANDBOX)
	CefScopedSandboxInfo scoped_sandbox;
	sandbox_info = scoped_sandbox.sandbox_info();
#endif

	// Parse command-line arguments.
	CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
	command_line->InitFromString(::GetCommandLineW());

	// Create a ClientApp of the correct type.
	CefRefPtr<CefApp> app;
	// The command-line flag won't be specified for the browser process.
	if (!command_line->HasSwitch("type"))
	{
		app = new BrowserApp();
	}
	else
	{
		const std::string& processType = command_line->GetSwitchValue("type");
		if (processType == "renderer")
		{
			app = new RenderApp();
		}
		else
		{
			// 其他进程就不创建了,本地只管理browser和render进程
			//return 0;
			//app = new ClientAppOther();
		}
	}

	// Execute the secondary process, if any.
	int exit_code = CefExecuteProcess(main_args, app, sandbox_info);
	if (exit_code >= 0)
		return exit_code;


	// Specify CEF global settings here.
	CefSettings settings;

#if !defined(CEF_USE_SANDBOX)
	settings.no_sandbox = true;
#endif

	CefSettingsTraits::init(&settings);
	//这个设置能实现单进程运行Cef浏览器插件,我们实际应用中采用的是双进程模式,即一个主进程,一个render渲染进程  
	//settings.single_process = true;
	//settings.no_sandbox = true;  

	//设置渲染进程的名称,因为在相同目录下,没有指定路径  
	//CefString(&settings.browser_subprocess_path).FromWString(L"Render.exe");

	//禁用Cef的消息循环,采用DuiLib的消息循环  
	//settings.multi_threaded_message_loop = true;

	//设置本地语言  
	//CefString(&settings.locale).FromWString(L"zh-CN");

	//缓存数据路径  
	std::wstring strPath = GetModuleDir();
	strPath = strPath + _T("\\Cef_cache");
	CefString(&settings.cache_path).FromWString(strPath);

	//debug日志路径  
	//CefString(&settings.log_file).FromWString(log_file);

	// Initialize CEF.
	CefInitialize(main_args, settings, app.get(), sandbox_info);

	// Run the CEF message loop. This will block until CefQuitMessageLoop() is
	// called.
	CefRunMessageLoop();

	// Shut down CEF.
	CefShutdown();

	return 0;
}

浏览器初始化结束后,开启消息循环,退出时,结束消息循环,从这里返回,然后调用CefShutdown(), 结束应用。

MFC项目,debug模式有的Cef版本会有问题。这里用了“有的”,不错,这就是问题的关键,MFC项目集成,debug模式退出崩溃的问题大部分是因为Cef版本的问题。套路都是在OnBeforeClose中CefQuitMessageLoop,然后在应用程序返回之前CefShutdown。

不过这个问题是发生在debug模式下,release正常。

 

猜你喜欢

转载自blog.csdn.net/moyebaobei1/article/details/81556685
CEF