1.1将源代码编译成托管代码模块
如上图,用支持CLR的任何一种语言来创建源代码文件。再用一个对应的编译器来检查语法和分析源代码。经编译器编译后生成托管模块(managed module),它是一个可移植执行体文件,它可能是32位(PE32)文件,也可能是64位(PE32+)文件。托管模块包括中间语言和元数据,需要CLR才能执行。
公共语言运行时(Common Language Runtime, CLR)是一个供多种编程语言使用的运行时。可用任何编程语言来开发代码,只要编译器是面向CLR的就行。
CLR也可以看作是一个在执行时管理代码的代理,管理代码是CLR的基本原则。能够被管理的代码称为托管(managed)代码,反之称为非托管代码。
CLR的核心功能中的内存管理、程序集加载、安全性、异常处理和线程同步等可被面向CLR的所有语言使用。
托管模块是一个需要CLR环境才能执行的标准windows PE文件,包含IL和元数据以及PE表头和CLR表头。:
- PE32/PE32+ 头:标准的 Windows PE文件头。包含文件类型(如GUI、CUI等),以及文件创建时间等信息。如果文件头使用PE32格式,则此文件只能在Windows 的32位或64位版本上运行;如果文件头使用PE32+格式,则此文件只能在Windows 的64位版本上运行。
- CLR表头:包含标识托管模块的一些信息。如CLR版本号,托管模块入口点方法(main方法)以及MethodDef元数据等等。
- IL代码:也是中间语言。编译器编译源代码时生成的中间代码,在执行环境中,这些IL代码将被CLR的JIT编辑器翻译成CPU能识别的指令,供CPU执行。
- 元数据实际上是一个数据表集合,用来描述托管模块中所定义和引用的内容。VS能够智能感知就得益于元数据的描述。
PE (Portable Execute) 文件是微软Windows操作系统上的程序文件,EXE、DLL、OCX、SYS、COM都是PE文件。
本地代码编译器(native code compiler)生成的是面向特定CPU架构(比如x86,x64)的代码。相反,每个面向CLR的编译器生成的都是IL代码。
中间语言IL(Intermediate Language)代码:编译器编译源代码后生成的代码(.exe或.dll文件),但此时编译出来的程序代码并不是CPU能直接执行的机器代码。在运行时,CLR的JIT编辑器将IL代码编译成本地CPU指令。
CPU:中央处理器(Central Processing Unit),是一台计算机运算核心和控制核心。它的功能主要是解释计算机指令以及处理计算机软件中的数据。
DLL (Dynamic Link Library) 文件为动态链接库文件,是一种作为共享函数库的可执行文件。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。多个应用程序也可以同时访问内存中单个 DLL 副本的内容。DLL 有助于共享数据和资源。
动态链接与静态链接的不同之处在于:动态链接允许可执行模块(.dll 文件或 .exe 文件)仅包含在运行时定位 DLL 函数的可执行代码所需的信息。在静态链接中,链接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。
使用中间语言的优点(跨平台,跨语言):
- 可以实现平台无关性,即与特定CPU无关。
- 只需把.NET框架中的某种语言编译成IL代码,就实现.NET框架中语言之间的交互操作。
元数据(Metadata)是描述数据(类型信息) 的数据,通常被解释为data about data,是由一组数据表构成的一个二进制数据块。元数据被CLR编译器编译后保存在Windows可移植执行体(PE)文件中,即和它描述的IL嵌入在EXE/DLL文件中,使IL和元数据永远同步。
元数据主要的类型表:
- 定义表 描述当前程序集中定义的类型和成员信息。
- 引用表 描述任何一个被内部类型引用的外部的类型和成员信息。
- 清单表包含了组成程序集所需要的所有信息,同时包含了对其他程序集的引用信息。
元数据的用途:
- 编译时,元数据消除了对本地C/C++头和库文件的需求,因为在负责实现类型/成员的IL代码文件中,已包含和 引用的类型/成员有关的全部信息。编译器可以直接从托管模块读取元数据。
- CLR的代码验证过程中使用元数据确保代码只执行“类型安全”的操作。
- VS使用元数据帮助您写代码。它的“智能感知”(IntelliSense)技术可以解析元数据,指出一个类型提供了哪些方法、属性、事件和字段。
- 元数据允许将一个对象的字段序列化到一个内存中,将其发送给另一台机器。然后反序列化,在远程机器上重建对象的状态。(内存:与CPU进行沟通的桥梁,计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大)。
- 元数据允许垃圾回收器跟踪对象的生存期,垃圾回收器能判断任何对象的类型,并从元数据知道那个对象中哪些字段引用了其他对象。