鸟语天空
CLR寄宿
post by:追风剑情 2020-10-28 9:55

公共语言运行库 (common language runtime,CLR) 是托管代码执行核心中的引擎。

      .NET Framework在Windows平台的顶部运行。这意味着.NET Framework必须用Windows能理解的技术来构建。首先,所有托管模块和程序集文件都必须使用Windows PE文件格式,而且要么是Windows EXE文件,要么是DLL文件。

      开发CLR时,Microsoft实际是把它实现成包含在一个DLL中的COM服务器。也就是说Microsoft为CLR定义了一个标准的COM接口,并为该接口和COM服务器分配了GUID。安装.NET Framework时,代表CLR的COM服务器和其他COM服务器一样在Windows注册表中注册。要了解这方面的更多信息,可参考与.NET Framework SDK一起发布的C++头文件MetaHost.h。该头文件中定义了GUID和非托管ICLRMetaHost接口。

      任何Windows应用程序都能寄宿(容纳)CLR。但不要通过调用CoCreateInstance来创建CLR COM服务器的实例,相反,你的非托管宿主应该调用MetaHost.h文件中声明的CLRCreateInstance函数。CLRCreateInstance函数在MSCorEE.dll文件中实现,该文件一般在C:\Windows\System32目录中。这个DLL被人们亲切地称为“垫片”(shim),它的工作是决定创建哪个版本的CLR;垫片DLL本身不包含CLR COM服务器。

① 使用64位Windows实际会安装两个版本的MSCorEE.dll文件。一个是32位x86版本,在C:\Windows\System32目录中;另一个是64位x64或IA64版本(取决于计算机的CPU架构),在C:\Windows\SysWOW64目录中。

      一台机器可安装多个版本的CLR,但只有一个版本的MSCorEE.dll文件(垫片)。机器上安装的MSCorEE.dll是与机器上安装的最新版本的CLR一起发布的那个版本。所以,该版本的MSCorEE.dll知道如何查找机器上的老版本CLR。

      包含实际CLR代码的文件的名称在不同版本的CLR中是不同的。版本1.0,1.1和2.0的CLR代码在MSCorWks.dll文件中;版本4则在Clr.dll文件中。由于一台机器可能安装多个版本的CLR,所以这些文件安装到不同的目录,如下所示:

② 注意,.NET Framework 3.0和3.5是与CLR2.0一起发布的。我没有显示.NET Framework 3.0和3.5的目录,因为CLR DLL是从v2.0.50727目录加载的。

      CLRCreateInstance函数可返回一个ICLRMetaHost接口。宿主应用程序可调用这个接口的GetRuntime函数,指定宿主要创建的CLR的版本。然后,垫片将所需版本的CLR加载到宿主的进程中。

      默认情况下,当一个托管的可执行文件启动时,垫片会检查可执行文件,提取当初生成和测试应用程序时使用的CLR的版本信息。但应用程序可以在它的XML配置文件中设置requiredRuntime和supportedRuntime这两项来覆盖该默认行为。

      GetRuntime函数返回指向非托管ICLRRuntimeInfo接口的指针。有了这个指针后,就可利用GetInterface方法获得ICLRRuntimeHost接口。宿主应用程序可调用该接口定义的方法来做下面这些事情:

注意  Windows进程完全可以不加载CLR,只有在进程中执行托管代码时才进行加载。在.NET Framework 4之前,CLR只允许它的一个实例寄宿在Windows进程中。换言之,在一个进程中,要么不包含任何CLR,要么只能包含CLR v1.0,CLR v1.1或者CLR 2.0之一。每进程仅一个版本的CLR显然过于局限。例如,这样Microsoft Office Outlook就不能加载为不同版本的.NET Framework生成和测试的两个加载项了。
但是,随着.NET Framework 4的发布,Microsoft支持在一个Windows进程中同时加载CLR v2.0和v4.0,为.NET Framework 2.0和4.0写的不同组件能同时运行,不会出现任何兼容性问题。这是一个令人激动的功能,因为它极大扩展了.NET Framework组件的应用场合。可利用ClrVer.exe工具检查给定的进程加载的是哪个(哪些)版本的CLR。
一个CLR加载到Windows进程之后,便永远不能卸载;在ICLRRuntimeHost接口上调用AddRef和Release方法是没有作用的。CLR从进程中卸载的唯一途径就是终止进程,这会造成Windows清理进程使用的所有资源。


评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容