Xilium.CefGlue与CEF库的版本匹配关系

今天我试着搭建一个最简单的Xilium.CefGlue项目,这是一个基于CEF3类库的.NET项目 (CEF是Chromium Embedded Framework的简称) ,对WebKit内核进行了封装(WebKit即Chrome浏览器使用的内核),并提供给.NET程序使用。

Xilium.CefGlue的下载地址:

https://bitbucket.org/xilium/xilium.cefglue/downloads

这个版本下载后,我用VS2012打开,将不必要的程序集都卸载掉,只留下Winform版本的程序集,并指定它为启动程序集。

此时直接编译并运行后,会提示报错信息

System.DllNotFoundException: 无法加载DLL "libcef":找不到指定的模块。(异常来自 HRESULT:0x8007007E)

这是因为我们没有将CEF3类库放入到Xilium.CefGlue工程的Debug目录下

我们可以从 https://cefbuilds.com/ 上下载CEF3类库编译好的版本:

这里选择版本非常有讲究。所以我们先不着急下载,而是先研究下我们应该下载那个版本。

回到解决方案Xilium.CefGlue,找到CefGlue程序集→Interop→version.g.cs文件

文件中代码如下:

//
// DO NOT MODIFY! THIS IS AUTOGENERATED FILE!
//
namespace Xilium.CefGlue.Interop
{
    using System;
    using System.Runtime.InteropServices;
    using System.Diagnostics.CodeAnalysis;
    
    internal static unsafe partial class libcef
    {
        public const string CEF_VERSION = "3.2704.1425.gaf7a122";
        public const int CEF_VERSION_MAJOR = 3;
        public const int CEF_COMMIT_NUMBER = 1431;
        public const string CEF_COMMIT_HASH = "af7a122be59d08a792028e4d98c537a0cd97a308";
        
        public const int CHROME_VERSION_MAJOR = 51;
        public const int CHROME_VERSION_MINOR = 0;
        public const int CHROME_VERSION_BUILD = 2704;
        public const int CHROME_VERSION_PATCH = 84;
        
        public const string CEF_API_HASH_UNIVERSAL = "91cfa692777eb302c24c66da0e70218e89346a49";
        public const string CEF_API_HASH_PLATFORM_WIN = "770131916655f914b4659d82ef08993bf9cfdc22";
        public const string CEF_API_HASH_PLATFORM_MACOSX = "e2bc35a1769ac92d76454f2e5696c3cfb42d262b";
        public const string CEF_API_HASH_PLATFORM_LINUX = "f2e0e25e03311ba94801d3f358ca3f4da4255758";
    }
}

其中指定了下面三项:

CEF_COMMIT_NUMBER,提交号,这里是1431

CEF_API_HASH_PLATFORM_WIN,Windows环境下的CEF_API_HASH码

CHROME_VERSION_BUILD,构建版本号,这里是2704

所以我们在cefbuilds.com找到branch2704

将这个7z压缩包下载到本地并解压缩,找到Debug和Resources两个目录,将其中的内容全部复制到Xilium.CefGlue项目的Debug目录中。

在下载到本地的CEF类库源码中,找到 \include\cef_version.h 可以发现其中有如下代码:

// .............

#define CEF_VERSION "3.2704.1431.ge7ddb8a"
#define CEF_VERSION_MAJOR 3
#define CEF_COMMIT_NUMBER 1431
#define CEF_COMMIT_HASH "e7ddb8a9a9f3bf95d5c0e5c2d6d213ee2280988f"
#define COPYRIGHT_YEAR 2016

#define CHROME_VERSION_MAJOR 51
#define CHROME_VERSION_MINOR 0
#define CHROME_VERSION_BUILD 2704
#define CHROME_VERSION_PATCH 84

// .............

// The API hash is created by analyzing CEF header files for C API type
// definitions. The hash value will change when header files are modified
// in a way that may cause binary incompatibility with other builds. The
// universal hash value will change if any platform is affected whereas the
// platform hash values will change only if that particular platform is
// affected.
#define CEF_API_HASH_UNIVERSAL "a4358963bc66adefedbf3008a83007e89afffab9"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "770131916655f914b4659d82ef08993bf9cfdc22"
#elif defined(OS_MACOSX)
#define CEF_API_HASH_PLATFORM "95517cba92239cc69c4267a649c6dad0781f245c"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "5963da3614d469320c9cc726ce7d838280132c26"
#endif

// .............

编译完毕后生成的动态库文件libcef.dll的版本号也与这几个宏有关系。

我们根据这个码,修改Xilium.CefGlue项目中的version.g.cs,如不修改,程序在运行时会报错:

严格意义上讲这一步修改是有风险的,因为CEF_API_HASH是自动生成的,且只有在头文件被修改过时才会改变,但坑爹的是Xilium.CefGlue使用的CEF3库版本并不是正式发布版,而是具体到某一次Commit的版本,这就非常恶心了,如果你想把指定Commit号的完成代码Checkout出来自己编译一发,自然是再好不过,但如果你没有这么多的时间和精力,那找一个版本最接近的CEF3库正式发布版也是一个选择,如果你还不放心这之间CEF3库都被做过哪些改动,可以在Commit记录中查看修改记录:

https://code.google.com/archive/p/chromiumembedded/source/default/commits

修改完毕后,就可以编译并运行了,如下图:

没有更多推荐了,返回首页