码迷,mamicode.com
首页 > 其他好文 > 详细

The CLR’s Execution Model

时间:2015-05-22 19:01:45      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

微软.NET Framework介绍了很多概念、技术和术语。在这一章我的目标是给你一个概述,.NET Framework是怎么设计的,介绍你一些框架包含的技术,和定义的很多术语,当你开始使用.NET Framework的时候将会看到这些。我也将通过带你建立你自己的源码应用程序或者设置一个可再使用的组件(文件集)包含(类,枚举,等等)向你解释一个应用程序是将怎么执行。

?

Compiling Source Code into Managed Modules(编译源码到托管模块)

那么你已经决定使用.NET Framework作为你的开发平台了。你的第一步是决定你想要开发的是哪一种类型的应用程序或者组件。让我们来假定你已经完成了这个小细节;每一件事都已经设计好了,规格说明书都已近写好了,并且你已经准备开发了。

现在你必须决定要使用哪一种开发语言。这个任务一般都很困难,因为不同的语言拥有不同的能力。比如,非托管的C/C++,你能控制底层的系统。你能通过你想要的方式精确的管理内存,当你想创建线程的时候很容易,等等。微软Visual Basic 6.0,在另一方面,允许你快速的创建UI应用程序和可以让你容易的控制COM组件和数据库。

公共语言运行库(CLR)正如它的名字一样:runtime可用于不同的和各种各样的编程语言。CLR的核心特征(比如内存管理,程序集加载,安全,异常处理,和线程同步)可适用于任何和所有编程语言只要编译目标期间是CLR。比如,runtime使用异常报告错误,所以所有编译目标是runtime的编程语言获得错误报告都是通过异常得到的。另一个例子是runtime允许你创建线程,所以所有编译目标是runtime的编程语言都可以创建线程。

事实上,在runtime库中,CLR不知道开发者使用哪一种开发语言写的源码。这意味着你选择的开发语言应该是最容易表达你的意图的。你可以用任何你想用的开发语言只要你使用的编译器能把你的代码编程成CLR

所以,假如我说的真的,使用某个开发语言而不使用另一个开发语言有什么好处?好吧,我认为编译器作为语法检查者和"代码纠错"分析者。它们检查你的源代码,确保你写的源码有一些道理,然后输出描述你意图的代码。不同的编程语言允许你在开发时使用不同的语法。不要低估选择开发语言的价值。比如,对于数学或者财政应用程序,使用APL语法表达你的开发意图可以节省很多天开发时间相较于使用Perl语法表达相同的开发意图。

微软已经创建了几门语言编译器编译成runtimeC++CLIC#(发音"C sharp"),Visual BasicF#(发音"F sharp")Iron PythonIron Ruby,和IL汇编。除微软外,另外几家公司、大学都创建了编译器并且产生的代码目标是CLR。我知道的编译器可编译的语言有AdaAPLCamlCOBOLEiffelForthFortranHaskellLexicoLISPLOGOLuaMercuryMLMondrianOberonPascalPerlPHPPrologRPGSchemeSmallTalk Tcl/Tk

下图指出了程序编译源码文件。如图所示,你可以使用任何支持CLR的编程语言创建源码文件集。然后你可以使用相应的编译器检查语法和分析源码。不管你使用哪一个编译器,结果都是托管组件。一个托管模块是一个标准的32位Windows PE32文件或者标准64位Windows PE32+文件只能在CLR执行。顺便说一句,在Windows中托管程序集会得到DEPASLR的好处,这两个特征提高了你整个系统的安全性。

图表描述了托管模块的组件。

?

托管组件组成部分

组件名称

描述

PE32或者PE32+ header

标准Windows PE文件头,它和COFF(Common Object File Format)的头文件很像。假如头文件使用PE32转换,那么所转换文件可在32位或者64位的Windows系统上运行。假如头文件使用PE32+转换,那么文件只能在64位版本的Windows系统上运行。头文件也规定了文件的格式:GUI,CUI,或者DLL,并且包含一个文件何时创建的时间戳。对于只包含IL代码的模块,大部分在PE32(+)头文件中的信息都会被忽略。对于包含本地CPU代码的模块,这个头文件包含了本地CPU代码信息。

CLR header

包含标记当前模块为托管模块的信息(通过CLR和工具解释得来的信息)。头文件包含所需的CLR版本,一些标记,托管模块方法(Main method)入口点的MethodDef元数据令牌。模块元数据的位置和大小,资源,强命名,一些标记,和其他少量的有趣的东西。

元数据

每个托管模块都包含元数据表单。所有的表单中有两个主要的分类:一种是描述你源码中定义的类型和成员,另一种是描述源码中的被引用的类型和成员。

IL Coder

编译器编译产生的代码。在运行时,CLRIL编译成本地CPU指令。

本地代码编译器按照指定的CPU架构生成代码,比如x86x64,或者ARM。所有顺从CLR编译器的都会生成IL。(我在后面的章节会深入更多的IL代码细节。)IL代码有时会被归为托管代码,因为CLR管理它的执行。

除了生成IL,每一个以CLR为编译目标的编译器都要求在每个托管模块中生成所有元数据。简而言之,元数据是数据表的一个设置,描述了在模块中定义了什么,比如类型和成员。此外,元数据也有表指出托管模块的引用,比如导入的类型和导入的成员。元数据是老技术的一个超集,比如COM‘s Type LibrariesInterface Definition Language(IDL) 文件。重点需要注意的是CLR元数据更完整。并且,不同于Type LibrariesIDL,元数据一直是和包含IL代码的文件是关联的。事实上,元数据一直作用代码嵌入到相同名字的EXE/DLL中,使具有相同名字的EXE/DLL不能分离。因为编译器生成元数据和代码的同时把它们绑定到托管模块,元数据和IL代码不能分开描述。

下面是元数据的一些用处:

*编译时元数据移除本地的C/C++头文件和库文件需求因为所有类型/成员引用信息已经包含在IL中,IL实现了类型/成员。编译器可以直接从托管模块中读取元数据。

*微软VS使用元数据帮助你写代码。它的智能提示特性通过转换元数据告诉你方法需要的属性,事件,和提供的字段类型,在一个方法中该方法需要什么参数。

*CLR的代码验证程序使用元数据确保你的代码执行时类型安全。

*元数据允许一个对象的字段系列化为内存块,发送给另一个机器,然后反系列化,在远程机器上重建对象的状态。

*元数据允许垃圾回收器跟踪对象的生命周期。对于任何对象来说,垃圾回收器能决定对象是何种类型,通过元数据,知道哪一个对象所包含的字段被另一个对象引用。

在第二章,"生成,打包,部署,管理程序和类型",我将讲更多的元数据细节。

微软的C#Visual BasicF#,和IL Assembler总是生成包含托管代码(IL)和托管数据(回收数据类型)的模块。为了执行包含托管代码或者托管数据的模块,最终用户必须在他们的机器安装了CLR(目前作为.NET Framework的一部分),同样的,他们也需要安装Microsoft Foundation Class(MFC)库或者Visual Basic DLLs才能运行MFC或者Visual Basic 6.0程序。

默认的,微软的C++编译器生成包含非托管(本地)代码和可以操作非托管数据(本地内存)EXE/DLL的模块在运行时。这些模块不需要CLR执行。无论如何,通过指定CLR命令行转换,C++编译器生成的模块将包含托管代码,这样一来,要执行这些代码就需要安装CLR了。微软所有的编译器都提到,C++是唯一编译器可允许程序员写托管和非托管代码的编程语言并且放到一个模块中。C++也是微软编译器唯一允许开发者在源码中定义托管和非托管数据类型的语言。和其他编译器相比微软的C++编译器的灵活性是无以伦比的,因为它允许开发者使用已存在的本地托管C/C++代码并且开始集成开发者看到适合的托管类型。

?

Combining Managed Modules into Assemblies(组合托管模块为程序集)

CLR实际上不是依靠模块工作,而是依赖程序集。程序集是一个抽象概念刚开始很领会。首先,一个程序集是一个逻辑组对应一个或多个模块或源文件集。第二,一个程序集是可重用的、安全的、版本化的最小单元。根据你使用的编译器或工具你可以选择生成一个文件或一个多文件程序集。在CLR的世界里,一个程序集就是我们叫的组件。

The CLR’s Execution Model

标签:

原文地址:http://www.cnblogs.com/Zhang-Xiang/p/4520338.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!