编译环境:VS2019 + Win10 + cmake-gui-3.8.0 + cef_binary_3.2623.1401.gb90a3be_windows32

最后一个兼容Windows XP的CEF(2623)的下载地址:https://pan.baidu.com/s/1UoWt8Ffs_YPBCmYlHbipLg

提取码:x7ym

1、解压 cef_binary_3.2623.1401.gb90a3be_windows32 后,目录如下:

2、下载cmake-gui

下载地址:https://pan.baidu.com/s/1KdOaZXWX9gy7yVKVbJdpgA

提取码:ptnu

下载好cmake-gui并安装好之后打开cmake-gui.exe,设置如下:

Where is the source code : cef_binary_3.2623.1401.gb90a3be_windows32解压后的路径

where to build the binaries : cef_binary_3.2623.1401.gb90a3be_windows32解压后的路径

Configure: 选择你电脑上装有的VS的编译器的版本,如果选择了电脑本地并没有的VS编译器版本,会遇到如下情况:

用cmake生成编译工程时候报这样的错误,原因是配置错误导致cmake找不到对应的编译器,于是通过File->Delete cache清理配置,重新通过Configure更换你电脑上装有的VS的编译器的版本即可。

当出现Configuring done的时候点击Generate按钮即可生成对应版本的VS sln解决方案,使用VS打开生成解决方案即可。

VS2015打开cef.sln然后直接编译即可生成libcef_dll_wrapper.lib文件了,如下图项目cefsimple项目和cefclient项目会失败,这个并不影响生成我需要的libcef_dll_wrapper.lib,我就不解决了。

在这里还有一个坑就是这个工具最多只支持到VS2017,由于我的电脑上装了VS2013和VS2019,于是我选择了VS2013的配置并成功编译出了libcef_dll_warpper.lib,但在导入CEF浏览器实际项目调用的时候报了如下错误:error LNK2038: 检测到“_MSC_VER”的不匹配项问题。

_MSC_VER这个相当于做了宏的检测  _MSC_VER 定义编译器的版本。下面是一些编译器版本的_MSC_VER值:
MS VC++ 14.0 _MSC_VER = 1900 vs2015
MS VC++ 12.0 _MSC_VER = 1800 vs2013的编译器他的平台是v120
MS VC++ 11.0 _MSC_VER = 1700 vs2012的编译器他的平台是v110
MS VC++ 10.0 _MSC_VER = 1600 Visual C++ 2010
MS VC++ 9.0 _MSC_VER = 1500 Visual C++ 2008
MS VC++ 8.0 _MSC_VER = 1400 Visual C++ 2005
MS VC++ 7.1 _MSC_VER = 1310
MS VC++ 7.0 _MSC_VER = 1300
MS VC++ 6.0 _MSC_VER = 1200
MS VC++ 5.0 _MSC_VER = 1100

error LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1800”不匹配值“1700”(main.obj 中)
原因:由于你使用了vs2012,工作集选择了更高的1800也就是vs2013的,致使msvc不兼容!
方法:在项目(解决方案资源管理器或者属性管理器里都行)右键属性-配置属性-常规中,平台工具集选用为合适平台即可,比如上面的就是要选择成2012的 v11版本,注意光选了还没有用,还要应用。
注意一个工程里面会有几个解决方案的时候,需要给每个解决方案都更改一遍,最后重新编译即可。

最近在通过OpenHardWareMonitorLib来获得一些CPU和GPU的信息,采用了c++调用c#dll的方法,由于只能传递基本数据类型,所以动态数组考虑到使用String来传递回C++并进行字符串分割,在.net中string是需要用gcnew进行初始化,先来看看gcnew和普通的new的区别:

C++/CLI中使用gcnew关键字表示在托管堆上分配内存,并且为了与以前的指针区分,用^来替换* ,就语义上来说他们的区别大致如下:

1.     gcnew返回的是一个句柄(Handle),而new返回的是实际的内存地址. 
2.     gcnew创建的对象由虚拟机托管,而new创建的对象必须自己来管理和释放.
暂时没有很深入的去理解这些区别。因为需要在c++的控制代码中对c#产生的String^变量进行写出,而默认的文件写出是string类型的,因此需要进行转换。查阅资料发现有人总结了一下较为简单的转换方式:

1:std::string转String^:std::string stdstr=””;
String^ str = marshal_as<String^>(stdstr);

2:String^转std::string:
String^ str= gcnew String();
std::string stdstr = marshal_as(str->ToString());

3:CString转Sting^:
CString cstr=””;
String^ str = marshal_as(cstr.GetBuffer());
cstr.ReleaseBuffer();

4:String^转CString:
String^ str;
CString cstr(str);