CLR的执行模型(C#)
流程:1.将源代码编译成委托代码——>2.将委托代码合并成程序集——>3.执行程序集代码——>4.加载公共语言进行时
注:CLR(Common Language公共语言)CLR是一个可由多种编程语言使用的“运行时”。CLR的核心功能(e.g.内存管理、程序集加载、安全性、异常处理、线程同步等),可由面向CLR的所有语言使用。
1、将源代码编译成委托模块:
CLR根本不关心开发人员用那一种语言来写源代码,说明我我们写C#代码的时候肯定还经过一定的步骤才能跟CLR,于是就需要相应的面向CLR的、可以编译C#代码的编译器,以便CLR可以识别你写的东西。这个编译器会检查语法和分析源代码,产生的是一个托管模块
注: 托管模块是一个可以在CLR中执行的PE(Portal Executable)文件。
书中介绍托管模块由PE32或PE32+头、CLR头、元数据、IL(中间语言)代码。看的时候个人觉得理解元数据和IL比较重要。
元数据:包含两种类型的元数据表:一个表描述源代码中定义的类型和成员;另一个表描述源代码引用的类型和成员 。
IL(中间语言)代码:编译器编译源代码时生成的代码。在运行时,CLR将IL编译成本地CPU指令。(IL代码有时称为托管代码,因为CLR要管理它的执行)
2、将托管代码合并成程序集:(CLR实际不和模块一起工作。相反,他是和程序集一起工作的)
前面说到CLR不会识别你的具体语言,需要相应编译器生成相应的托管模块。这会又说实际不和模块一起工作,引入了程序集的概念。文中说程序集是一个抽象的概念。
托管模块(IL和元数据)、资源文件(.jepg,.gif,.html等)——>将多个托管模块和资源文件合并成程序集的工具(C#编译器 CSC.exe)——>程序集(清单:描述程序集中的文件集)
3、加载公共语言运行时:
你生成的程序集既可以是一个可执行的应用程序,也可以是一个DLL(其中含有一组可执行程序使用的类型)。最终由CLR管理这些程序集中的代码的执行。
加载公共语言进行时时window的事,我们可以考虑在window的一系列之后会初始化CLR,然后加载exe程序集,然后调用其入口方法Main()。随即,托管的应用程序将启动并运行。
4、执行程序集代码:
在第一步,即源代码编译成托管模块的时候提到:元数据总是和包含IL代码的文件关联,由于编译器同时生成元数据和代码,把他们绑定一起,并嵌入最终生成的托管模块,所以元数据和他描述的IL代码用惯不会失去同步
可想而知,当你调用入口方法(Main)的时候,元数据也跟着进来了,他们是一对好基友