第1章
下载    1

1.1 下载    1

1.2 合并    1

第2章 cmake    4

2.1 编译简介    4

2.2 下载cmake    4

2.3 运行cmake    5

第3章
编译进阶    7

3.1 创建项目    7

3.2 添加源文件    8

3.2.1 下载vcHelper    8

3.2.2 使用vcHelper    8

3.3 配置VC++项目    9

3.3.1 不使用预编译头文件    9

3.3.2 增加宏定义    10

3.3.3 设置头文件查找目录    11

3.4 其它    12

3.4.1 使用VC++2008编译    12

3.4.2 修改#include语句    13

第4章
入门示例    16

4.1 简介    16

4.2 创建项目    16

4.3 编码    17

4.3.1 修改stdafx.h    17

4.3.2 增加cefSimple.h    20

4.3.3 修改mfcCEF.h    21

4.3.4 修改mfcCEF.cpp    21

4.3.5 修改mfcCEFDlg.h    23

4.3.6 修改mfcCEFDlg.cpp    23

4.4 运行    24

4.5 程序运行逻辑    25

第1章
下载

1.1 下载

下载网址为:http://www.magpcss.net/cef_downloads/,显示如下图所示:

图1.1

下载后的文件名如下所示:

cef_binary_3.2785.1466.g80e473e_windows32.tar.tar

cef_binary_3.2785.1466.g80e473e_windows64.tar.tar

1.2 合并

解压上一节的两个压缩包,并使用 Beyond Compare 进行二进制比较,如下图所示:

图1.2

可见:只有 Debug、Release、Resources 三个文件夹中的某些文件存在差异。所以,可将32位的Debug、Release、Resources重命名为Debug32、Release32、Resources32;64位的Debug、Release、Resources重命名为Debug64、Release64、Resources64。然后,将两个文件夹合并。

笔者将两个文件夹合并到了W:\libCEF\v3.2785.1466\unzip,其目录结构如下图所示:

图1.3

第2章 cmake

2.1 编译简介

这里的编译主要指的是 libcef_dll_wrapper 的编译。它是libcef.dll的包装工程,客户端程序通过它可以间接的访问libcef.dll。

libCEF较早的版本(如3.2171.1979),包含有VC++项目文件(*.sln),可直接打开进行编译。目前的版本不再包含这些*.sln文件,使用VC++编译前可使用cmake程序生成*.sln文件。

2.2 下载cmake

cmake的下载网址为:https://cmake.org/download/。显示如下图所示:

图2.1

说明如下:

cmake-3.6.1.zip                cmake的源代码

cmake-3.6.1-win32-x86.msi        安装包(32 位)

cmake-3.6.1-win32-x86.zip        直接运行(32 位)

cmake-3.6.1-win64-x64.msi        安装包(64 位)

cmake-3.6.1-win64-x64.zip        直接运行(64 位)

这里,下载 cmake-3.6.1-win32-x86.zip 即可。

2.3 运行cmake

解压cmake-3.6.1-win32-x86.zip,运行cmake-gui.exe,将显示如下界面:

图2.2

"Where is the source code:"右边的文本框内请输入图1.3中CMakeLists.txt所在的目录,即W:\libCEF\v3.2785.1466\unzip。

"Where to build the binaries:"右边的文本框内请输入一个目录,cmake将在这个目录下生成VC++项目文件(*.sln;*.vcproj;*.vcxproj)。这个目录可以和"Where is the source code:"的设置相同。

单击上图的"Configure"按钮,将弹出上图右下角的界面。在这个界面里选择VC++编译器,如:使用vc2010编译64位程序,请选择"Visual Studio 10 2010 Win64"。这里选择Visual Studio 10 2010,然后单击"Finish"按钮。

单击上图的"Generate"按钮,cmake将在W:/libCEF/v3.2785.1466/make/vc2010里生成vc2010的项目文件cef.sln、ALL_BUILD.vcxproj……如下图所示:

图2.3

使用Visual Studio 2010打开上图的cef.sln,可以发现有五个项目。如下图所示:

图2.4

libcef_dll_wrapper        对libcef.dll的包装,是编译的重点

cefclient                一个调用libcef的示例程序,较复杂

cefsimple                一个调用libcef的示例程序,较简单

ZERO_CHECK            再次运行cmake程序,检查哪些文件被修改了

ALL_BUILD            编译它,则ZERO_CHECK、libcef_dll_wrapper、

cefclient、cefsimple将依次被编译

第3章
编译进阶

本章将说明如何在不使用cmake的情况下编译libcef_dll_wrapper。

3.1 创建项目

创建VC++静态库项目libcef_dll_wrapper。以VC++2010为例,创建项目时首先选择"Win32 Project",如下图所示:

图3.1

接下来的设置如下图所示:即创建一个静态库,不使用预编译头文件。

图3.2

3.2 添加源文件

将图1.3文件夹libcef_dll及其子文件夹下的所有源文件(*.cc)添加到上一节创建的VC++项目libcef_dll_wrapper里。

3.2.1 下载vcHelper

手动添加所有的源文件比较繁琐,可借助工具vcHelper来完成此项工作。其下载方法为:

1、进入百度网盘 http://pan.baidu.com/s/1gd7XDkf

2、进入目录 public\Tools\vcHelper

3、下载vcHelper的最新版本。

3.2.2 使用vcHelper

运行vcHelper,进入"源文件树"页面,如下图所示:

图3.3

接下来的操作步骤为:

1、拖放文件夹libcef_dll至"生成文件树"内的文本框内,文件夹libcef_dll的全路径名(上图中的W:\libCEF\v3.2785.1466\unzip\libcef_dll)即被自动添加到该文本框内。当然,也可手工输入或粘贴这个全路径名;

2、单击"生成文件树"按钮。根据上图可知:vcHelper找到了263个文件;

3、拖放VC++项目libcef_dll_wrapper所在文件夹(W:\libCEF\v3.2785.1466\libcef_dll_wrapper)至"替换文件树"内的文本框内。vcHelper将在该文件夹内查找所有的VC++工程文件(*.vcproj或*.vcxproj),并将其全路径名添加到相应的文本框内;

4、单击"替换文件树"按钮,文件树(263个文件)将被添加到VC++工程文件里。

打开项目libcef_dll_wrapper,可以看到源文件树。如下图所示:

图3.4

3.3 配置VC++项目

3.3.1 不使用预编译头文件

具体的配置如下图所示:

图3.5

3.3.2 增加宏定义

增加宏定义:USING_CEF_SHARED=1和NOMINMAX,如下图所示:

图3.6

USING_CEF_SHARED 有两个作用:

1、调用libcef.dll里的函数时,会使用__declspec(dllimport),详见include\internal\cef_export.h文件;

2、编译时防止有效代码被屏蔽,如文件libcef_dll\cpptoc\views\browser_view_delegate_cpptoc.h里有如下代码:

#ifndef USING_CEF_SHARED

#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")

#else // USING_CEF_SHARED

class CefBrowserViewDelegateCppToC

: public CefCppToC<CefBrowserViewDelegateCppToC, CefBrowserViewDelegate,

cef_browser_view_delegate_t> {

public:

CefBrowserViewDelegateCppToC();

};

#endif

不定义宏USING_CEF_SHARED,则有效代码(蓝色部分)将被屏蔽掉。

NOMINMAX的作用:取消宏min、max的定义,防止它们与std::min、std::max冲突。以下内容节选自windef.h

#ifndef NOMINMAX

#ifndef max

#define max(a,b) (((a) > (b)) ? (a) : (b))

#endif

#ifndef min

#define min(a,b) (((a) < (b)) ? (a) : (b))

#endif

#endif /* NOMINMAX */

亦即:定义宏NOMINMAX之后,宏min、max将不会被定义。

3.3.3 设置头文件查找目录

编译libcef_dll_wrapper时,需要用到W:\libCEF\v3.2785.1466\unzip\include目录下的头文件。为此,需要设置W:\libCEF\v3.2785.1466\unzip为头文件查找目录。具体设置如下图所示:

图3.7

上图中的../../../unzip是W:\libCEF\v3.2785.1466\unzip相对于文件W:\libCEF\v3.2785.1466\libcef_dll_wrapper\make-libT\vc2010\libcef_dll_wrapperT.vcxproj的相对路径。可用vcHelper获得这个相对路径,如下图所示:

图3.8

输入"基准目录/文件"和"绝对路径",单击按钮">>"即可获得相对路径。

3.4 其它

3.4.1 使用VC++2008编译

libcef_dll_wrapper默认情况下至少需要VC++2010才能编译通过。使用VC++2008编译时,会提示无法找到stdint.h,为此特做如下修改:

在include目录下新建文件stdint.h,其内容如下:

#pragma once

#if _MSC_VER >= 1600 //VC++2010 ~ VC++2015

#include <stdint.h>

#else

typedef signed char int8_t;

typedef short int16_t;

typedef int int32_t;

typedef unsigned char uint8_t;

typedef unsigned short uint16_t;

typedef unsigned int uint32_t;

typedef signed char int_least8_t;

typedef short int_least16_t;

typedef int int_least32_t;

typedef unsigned char uint_least8_t;

typedef unsigned short uint_least16_t;

typedef unsigned int uint_least32_t;

typedef char int_fast8_t;

typedef int int_fast16_t;

typedef int int_fast32_t;

typedef unsigned char uint_fast8_t;

typedef unsigned int uint_fast16_t;

typedef unsigned int uint_fast32_t;

#ifdef _WIN64

typedef __int64 intptr_t;

#else /* _WIN64 */

typedef int intptr_t;

#endif /* _WIN64 */

#endif

亦即:VC++2010及其以上版本直接包含自带的stdint.h头文件,否则就自定义int8_t、int16_t……

接下来,修改源代码中的#include <stdint.h>为#include "../../include/stdint.h"。注意双引号内的相对路径不要弄错。

3.4.2 修改#include语句

如图3.7所示,使用libCEF的客户端项目,必须设置libCEF的头文件查找目录,否则将无法正常编译。

以W:\libCEF\v3.2785.1466\unzip\libcef_dll\wrapper\libcef_dll_wrapper.cc为例进行说明。该文件包含如下代码:

#include "include/cef_app.h"

它其实想包含的是W:\libCEF\v3.2785.1466\unzip\include\cef_app.h。为此,需要设置W:\libCEF\v3.2785.1466\unzip为头文件查找目录,这样编译器在编译时就能顺利找到文件include/cef_app.h了。

现在,如果把#include语句修改一下,如下所示:

#include "../../include/cef_app.h"

编译W:\libCEF\v3.2785.1466\unzip\libcef_dll\wrapper\libcef_dll_wrapper.cc时,编译器会使用头文件W:\libCEF\v3.2785.1466\unzip\libcef_dll\wrapper\..\..\include\cef_app.h,即W:\libCEF\v3.2785.1466\unzip\include\cef_app.h。这样,不用设置头文件查找目录,编译器也能找到头文件cef_app.h了。

也就是说:将#include语句中的包含路径全部更改为相对路径,就不再需要设置头文件查找目录了。

#include语句那么多,手工逐条修改将是一项浩大的工程。可借助vcHelper完成此项工作。如下图所示:

图3.9

具体操作步骤如下:

1、设置"源文件目录"和"引用目录"为W:\libCEF\v3.2785.1466\unzip;

2、勾中"修改#include""语句"复选框,不要勾中"修改#include<>语句"复选框,不要勾中"修改#include里的扩展名"

3、单击"扫描"按钮;

4、单击"自动修改"按钮,vcHelper将自动修改#include""语句,并将无法修改的语句显示到右侧的列表中;

5、右侧列表中,单击"数量"列标题,整个列表将按数量进行排序。数量2表示包含文件(ef_callback.h或resource.h)有两个。此时鼠标左键双击该行,将显示如下界面:

图3.10

单击按钮"UltraEdit",vcHelper将调用UltraEdit,并打开文件urlrequest_test.cc,然后跳转至第10行。如下图所示:

图3.11

根据上图可知,urlrequest_test.cc需要的是base目录下的cef_callback.h。因此应该选择图3.10中的第一条修改建议。鼠标左键双击此修改建议,然后粘贴到上图的第10行,即可完成此行语句的修改。

注意:如果vcHelper无法正常调用UltraEdit,请在vcHelper的Config.txt里配置UltraEdit的全路径名,如下图所示:

图3.12

第4章
入门示例

4.1 简介

本章参考了开源项目CEF3SimpleSample,其下载网址为:

https://github.com/acristoffers/CEF3SimpleSample

CEF3SimpleSample是一个SDK程序,本章对其进行精简,并使用了MFC。最终实现了如下图所示的效果——运行后将显示新浪网的首页。

图4.1

4.2 创建项目

创建一个MFC的对话框程序mfcCEF。创建项目时的配置请见下图:

图4.2

4.3 编码

4.3.1 修改stdafx.h

在stdafx.h的最后增加如下代码

#define STR(x) #x

#define STR2(x) STR(x)

#define INCLUDE(f) STR2(PATH(f))

//包含 libCEF 的头文件

//下面的宏定义,##之前是 libCEF include 目录相对于本文件的相对路径

#define PATH(f) ../../libCEF/v3.2785.1466/unzip/include/##f

#define USING_CEF_SHARED 1

#include INCLUDE(cef_app.h)

#include INCLUDE(cef_client.h)

#undef PATH

#include
"cefSimple.h"

//下面的宏定义是 libCEF 库文件相对于 vc 项目文件(*.vcproj/*.vcxproj)的相对路径

#define PATH "../../libCEF/v3.2785.1466/"

//连接库文件 libcef.lib

#ifdef _WIN64

#ifdef _DEBUG

#define PATH1 "unzip/Debug64/"

#else

#define PATH1 "unzip/Release64/"

#endif

#else

#ifdef _DEBUG

#define PATH1 "unzip/Debug32/"

#else

#define PATH1 "unzip/Release32/"

#endif

#endif

#pragma
comment(lib,PATH PATH1 "libcef.lib")

#undef PATH1

//连接库文件 libcef_dll_wrapper.lib

#define PATH1 "libcef_dll_wrapper/bin/"

#if _MSC_VER==1500 //VC++9.0(VC2008)

#define PATH2 "vc2008"

#elif _MSC_VER==1600 //VC++10.0(VC2010)

#define PATH2 "vc2010"

#elif _MSC_VER==1700 //VC++11.0(VC2012)

#define PATH2 "vc2012"

#elif _MSC_VER==1800 //VC++12.0(VC2013)

#define PATH2 "vc2013"

#elif _MSC_VER==1900 //VC++14.0(VC2015)

#define PATH2 "vc2015"

#else

#error
未知的 VC++ 编译器

#endif

#ifdef _WIN64

#define PATH3 "-x64"

#else

#define PATH3 "-Win32"

#endif

#ifdef _DEBUG

#ifdef _UNICODE

#define PATH4 "-DU/"

#else

#define PATH4 "-DA/"

#endif

#else

#ifdef _UNICODE

#define PATH4 "-RU/"

#else

#define PATH4 "-RA/"

#endif

#endif

#ifdef _MT

#ifdef _DLL //使用多线程 DLL 版的 C 函数库

#define PATH5 "libcef_dll_wrapperD.lib"

#else
//使用多线程版的 C 函数库

#define PATH5 "libcef_dll_wrapperT.lib"

#endif

#else
//使用单线程版的 C 函数库

#define PATH5 "libcef_dll_wrapperS.lib"

#endif

#pragma
comment(lib,PATH PATH1 PATH2 PATH3 PATH4 PATH5)

#undef PATH1

#undef PATH2

#undef PATH3

#undef PATH4

#undef PATH5

#undef PATH

#undef STR

#undef STR2

#undef INCLUDE

说明:

1、#define USING_CEF_SHARED 1 表示导入libcef.dll的导出函数;

2、VC++编译预处理器对#include INCLUDE(cef_app.h)的预处理:

首先变为 #include STR2(PATH(cef_app.h))

然后变为 #include STR(../../libCEF/v3.2785.1466/unzip/include/cef_app.h)

最后变为 #include "../../libCEF/v3.2785.1466/unzip/include/cef_app.h"

"#define PATH(f) ../../libCEF/v3.2785.1466/unzip/include/##f"中的../../libCEF/v3.2785.1466/unzip/include/是libCEF include 目录(W:\libCEF\v3.2785.1466\unzip\include)相对于本文件(W:\VC\mfcCEF\stdafx.h)的相对目录。请根据实际情况修改这个相对路径。

注意:若要使用相对路径包含libCEF头文件,请按照3.4.2节的说明把libCEF源代码里的#include语句都修改掉。

3、如果使用vc2010编译器,编译Debug版,则#pragma comment(lib,PATH PATH1 "libcef.lib")将被展开为:#pragma comment(lib,"../../libCEF/v3.2785.1466/" "unzip/Debug32/" "libcef.lib")也就是#pragma comment(lib,"../../libCEF/v3.2785.1466/unzip/Debug32/libcef.lib")。

../../libCEF/v3.2785.1466/unzip/Debug32/libcef.lib是库文件(W:\libCEF\v3.2785.1466\unzip\Debug32\libcef.lib)相对于vc项目文件(W:\VC\mfcCEF\mfcCEF.vcxproj)的相对路径。请根据实际情况修改"#define PATH "../../libCEF/v3.2785.1466/""中的相对路径。

4、libcef_dll_wrapper库文件

笔者的电脑上libcef_dll_wrapper库文件的路径为:

W:\libCEF\v3.2785.1466\libcef_dll_wrapper\bin\vc2010-Win32-RU

vc2010还有可能是vc2012/vc2013/vc2015

Win32还有可能是x64

RU(Release Unicode)还有可能是RA(Release Ansi)、DA(Debug Ansi)、DU(Debug Unicode)

库文件名有两种:

libcef_dll_wrapperT.lib        使用的C函数库是多线程版

libcef_dll_wrapperD.lib        使用的C函数库是多线程DLL版

如果客户端程序Use MFC in a Static Library,就会自动连接libcef_dll_wrapperT.lib;如果客户端程序Use MFC in a Shared DLL,就会自动连接libcef_dll_wrapperD.lib。

4.3.2 增加cefSimple.h

给项目增加头文件cefSimple.h,其内容如下所示:

#pragma
once

class SimpleApp : public CefApp

{

private:

IMPLEMENT_REFCOUNTING(SimpleApp);

};

class SimpleHandler : public CefClient

, public CefLifeSpanHandler

{

public:

SimpleHandler()

{

m_hWndBrowser = NULL;

}

public://CefClient methods:

virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler()

OVERRIDE { return
this; }

public://CefLifeSpanHandler methods:

virtual
void OnAfterCreated(CefRefPtr<CefBrowser> browser)

OVERRIDE {

m_hWndBrowser = browser->GetHost()->GetWindowHandle();

}

public:

HWND m_hWndBrowser;

IMPLEMENT_REFCOUNTING(SimpleHandler);

};

4.3.3 修改mfcCEF.h

修改后的内容如下

#pragma
once

#ifndef __AFXWIN_H__

#error "在包含此文件之前包含"stdafx.h"以生成 PCH 文件"

#endif

#include
"resource.h"

class CmfcCEFApp : public CWinApp

{

public:

CmfcCEFApp();

public:

virtual BOOL InitInstance();

DECLARE_MESSAGE_MAP()

};

extern CmfcCEFApp theApp;

4.3.4 修改mfcCEF.cpp

修改后的内容如下

#include
"stdafx.h"

#include
"mfcCEF.h"

#include
"mfcCEFDlg.h"

#ifdef _DEBUG

#define
new DEBUG_NEW

#endif

BEGIN_MESSAGE_MAP(CmfcCEFApp, CWinApp)

END_MESSAGE_MAP()

CmfcCEFApp::CmfcCEFApp()

{

}

CmfcCEFApp theApp;

BOOL CmfcCEFApp::InitInstance()

{

CWinApp::InitInstance();

_tsetlocale(LC_ALL,_T(""));

{//CEF 初始化

CefMainArgs ma(m_hInstance);

CefRefPtr<SimpleApp> app(new SimpleApp());

int nCEP = CefExecuteProcess(ma,app.get(),NULL);

if(nCEP >= 0) { exit(nCEP); }

CefSettings settings;

CefString(&settings.locale) = L"zh-CN";

settings.no_sandbox = 1;

settings.multi_threaded_message_loop = 1;

CefInitialize(ma, settings, app.get(),NULL);

}

{

CmfcCEFDlg dlg;

m_pMainWnd = &dlg;

dlg.DoModal();

}

CefShutdown(); //退出 CEF

return FALSE;

}

4.3.5 修改mfcCEFDlg.h

修改后的内容如下

#pragma
once

class CmfcCEFDlg : public CDialog

{

public:

CmfcCEFDlg(CWnd* pParent = NULL);

enum { IDD = IDD_MFCCEF_DIALOG };

protected:

virtual
void DoDataExchange(CDataExchange* pDX);

protected:

virtual BOOL OnInitDialog();

afx_msg void OnSize(UINT nType, int cx, int cy);

DECLARE_MESSAGE_MAP()

protected:

CefRefPtr<SimpleHandler> m_Handler;

};

4.3.6 修改mfcCEFDlg.cpp

修改后的内容如下

#include
"stdafx.h"

#include
"mfcCEF.h"

#include
"mfcCEFDlg.h"

#ifdef _DEBUG

#define
new DEBUG_NEW

#endif

CmfcCEFDlg::CmfcCEFDlg(CWnd* pParent /*=NULL*/)

: CDialog(CmfcCEFDlg::IDD, pParent)

,m_Handler(new SimpleHandler())

{

}

void CmfcCEFDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CmfcCEFDlg, CDialog)

ON_WM_SIZE()

END_MESSAGE_MAP()

BOOL CmfcCEFDlg::OnInitDialog()

{

CDialog::OnInitDialog();

CefWindowInfo wi;

RECT rc;

GetClientRect(&rc);

wi.SetAsChild(m_hWnd,rc);

CefBrowserSettings bs;

CefBrowserHost::CreateBrowser(wi,m_Handler.get()

,L"www.sina.com",bs,NULL);

return TRUE;

}

void CmfcCEFDlg::OnSize(UINT nType, int cx, int cy)

{

CDialog::OnSize(nType, cx, cy);

HWND hWnd = m_Handler->m_hWndBrowser;

if(hWnd)

{

RECT rc;

GetClientRect(&rc);

::MoveWindow(hWnd,0,0,rc.right,rc.bottom,FALSE);

Invalidate();

}

}

4.4 运行

编译mfcCEF成功后,先不要急着运行程序。因为mfcCEF.exe运行时需要一些文件,需要把它们复制到mfcCEF.exe所在目录。

假如mfcCEF.exe是32位的Release版,则

1、复制图1.3中Release32文件夹内的所有文件到mfcCEF.exe所在目录。注意:*.lib有259M,运行时不需要这些文件,所以就不用复制了。

2、复制图1.3中Resources32文件夹内的所有文件到mfcCEF.exe所在目录。

文件复制完成后,mfcCEF.exe所在目录如下图所示:

图4.3

现在,就可以运行mfcCEF.exe了。

4.5 程序运行逻辑

运行mfcCEF,代码的执行顺序如下:

1、执行 CmfcCEFApp::InitInstance,调用 CefInitialize 初始化 CEF;

2、CmfcCEFApp::InitInstance 里的 dlg.DoModal() 显示程序主界面;

3、程序主界面被创建时,执行 CmfcCEFDlg::OnInitDialog,调用 CefBrowserHost::CreateBrowser 创建浏览器窗口;

4、浏览器窗口创建完毕后,执行 SimpleHandler::OnAfterCreated,获得浏览器窗口的句柄 m_hWndBrowser;

5、浏览器窗口是程序主界面窗口的子窗口。调整主界面大小时,将执行 CmfcCEFDlg::OnSize。OnSize 函数里移动浏览器窗口(句柄为 m_hWndBrowser)使其占满主界面窗口的客户区;

6、用户退出主界面,CmfcCEFApp::InitInstance 里的 dlg.DoModal() 将返回。同时对象 dlg 将被析构,其成员变量m_Handler 也将被析构。CefRefPtr<SimpleHandler> 使用了计数功能,m_Handler 析构时计数值减一后等于零,new SimpleHandler() 创建的对象将被自动 delete;

7、CmfcCEFApp::InitInstance 里的 CefShutdown() 被执行,退出 CEF;

8、CmfcCEFApp::InitInstance 返回 FALSE,整个程序不进入消息循环,而是结束。

下面说明一下对象new SimpleApp()的生命周期:

1、CefRefPtr<SimpleApp> app(new SimpleApp()) 后对象的计数值为 1;

2、CefInitialize(ma, settings, app.get(),NULL) 后对象的计数值为2;

3、app 析构后对象的计数值为 1;

4、CefShutdown() 后,app 的计数值为 0,对象自动被 delete。

libCEF总结01下载、编译、入门的更多相关文章

  1. Java自动化测试框架-01 - TestNG之入门篇 - 大佬的鸡肋,菜鸟的盛宴(详细教程)

    TestNG是什么? TestNG按照官方的定义: TestNG是一个测试框架,其灵感来自JUnit和NUnit,但引入了一些新的功能,使其功能更强大,使用更方便. TestNG是一个开源自动化测试框 ...

  2. 【Android 系统开发】CyanogenMod 13.0 源码下载 编译 ROM 制作 ( 手机平台 : 小米4 | 编译平台 : Ubuntu 14.04 LTS 虚拟机)

                 分类: Android 系统开发(5)                                              作者同类文章X 版权声明:本文为博主原创文章 ...

  3. Tensoflw.js - 01 - 安装与入门(中文注释)

    Tensoflw.js - 01 - 安装与入门(中文注释) 参考 W3Cschool 文档:https://www.w3cschool.cn/tensorflowjs/ 本文主要翻译一些英文注释,添 ...

  4. Android 程序分析环境搭建-Android 9 -代码下载编译

    Android 9 -代码下载编译 一,翻墙下载: 1.背景: 背景: 现在Android framework 开发的同学,整体在公司里面解一些无关痛痒的bug,对于Android framework ...

  5. (1)redis下载编译

    一.redis下载编译 这里没什么好说的 用的版本是redis-2.8.17 1)redis-server是可执行程序 2)mian函数在redis.c里面 3)如果要修改调试 这届在src目录下   ...

  6. 下载编译Chrome详细步骤

    文章来源:http://blog.csdn.net/allendale/article/details/9262833 参考:http://dev.chromium.org/developers/ho ...

  7. 更新vs2017 15.9.2后,在指定-T v141_xp情况下载编译会报下面warning MSB8051

    更新vs2017 15.9.2后,在指定-T v141_xp情况下载编译会报下面warning: C:\Program Files (x86)\Microsoft Visual Studio\2017 ...

  8. Spring源码研究--下载-编译-导入eclipse-验证

    一,环境配置 操作系统:Unbutu14.04LTS JDK: 1.8.0_40 git: 1.9.1 gradle: 2.2.1 二,源码下载-编译-导入eclipse-验证 1,下载 使用git直 ...

  9. webrtc所有平台下载编译步骤详细说明

    webrtc所有平台下载编译步骤详细说明 1.安装depot tools Windows:国外下载:https://storage.googleapis.com/chrome-infra/depot_ ...

随机推荐

  1. WebForm 发送邮箱

    首先在设置发件邮箱的SMTP服务,以新浪邮箱为例:设置区----客户端pop/imap/smtp----"POP3/SMTP服务"和"IMAP4服务/SMTP服务&quo ...

  2. SqlSever基础 两个条件 group by 分组显示

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  3. SUSE Linux Enterprise Server 设置防火墙开启ssh远程端口

    1.vi /etc/sysconfig/SuSEfirewall2   #编辑防火墙设置 FW_SERVICES_EXT_TCP="22"   #开启22端口 rcSuSEfire ...

  4. SQL Server建表和增删改

    create database 数据库名 go --穿件完成 go create table 表名(列名 类型, 列名 类型, 列名 类型 --最后一个列名不加逗号) go --创建完成go 以创建表 ...

  5. hihoCoder太阁最新面经算法竞赛17

    比赛链接:http://hihocoder.com/contest/hihointerview26 A.排序后枚举两个点,确定一个矩形后二分剩下两个点. #include <bits/stdc+ ...

  6. Ubuntu下手动安装VMware Tools步骤

    To mount the CD image and extract the contents: Power on the virtual machine. Log in to the virtual ...

  7. log4j的使用(1) —— 简单入门篇

    这里会介绍三种打印日志的方法:控制台Console,文件File,数据库DataBase 1.下载lo4j的jar包并导入project 2.因为要在数据库添加日志,所以先新建一个库,并新建打印日志的 ...

  8. python_way day17 jQuery表单验证,事件绑定,插件,文本框架,正则表达式

    python_way day17 1.jQuery表单验证 dom事件绑定 jquery事件绑定 $.each return值的判断 jquery扩展方法 2.前段插件 3.jDango文本框架 4. ...

  9. hdu 5150 Sum Sum Sum 水

    Sum Sum Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Prob ...

  10. ruby的正则表达式-scan方法

    irb(main):001:0> str_vps=%Q{viewpoint_ids: [{"id":"260e053b-d728-4785-888d-eb4f1ca ...