C#程序的编译过程
C#程序的编译过程,如下图
总结:编译器将C#代码编译成DLL/EXE,DLL/EXE包含metadata(清单数据,对代码的描述)和IL(中间语言),IL(中间语言)经过CLR/JIT第二次编译才是机器码
一,程序的编译过程,步骤理解
1>C#源文件经过CSC.exe把Visual C#程序代码编译成IL文件(这里有很多参数和开关选项,参考 http://blog.chinaunix.net/uid-20715239-id-1219110.html),编译器编译生成程序集(exe dll)
2>c#代码第一次编译为一种伪代码称微软中间语言(MSIL)和元数据,MSIL和元数据同时储存在exe或dll 文件中,该伪代码是独立于任何CPU 的,所以只要装有.Net FrameWork的机器均可以运行该伪代码,这就增强了c#代码的可移植性。(ps.中间语言IL不是计算机识别语言,此IL文件不能直接被计算机使用)
3>程序执行时,该伪代码被CLR(Commom Language RunTime)捕获,CLR激活内部的 JIT(Just in time)编译器,将伪代码编译成针对特定CPU的机器语言,当然该步还要进行类型检查等,这样程序就能在任意合理的电脑中运行,得出结果。JIT 的意思为“仅在运行时编译”,整个代码的处理过程要编译两次。(PS:从IL文件到机器语言,这个工程是机器自动实现的)
二,JIT(即时编辑)又是什么?
1》JIT:即时编译(Just In-Time compile),这是.NET运行可执行程序的基本方式,也就是在需要运行的时候,才将对应的IL代码编译为本机指令。传入JIT的是IL代码(第一次编译生成的代码),输出的是本机代码(机器能识别的代码),然后把结果保存起来用于将来对同一方法的调用,直到应用程序结束,大大提高了效率,所以部分加密软件通过挂钩JIT来进行IL加密,同时又保证程序正常运行。同解释执行的代码相比,JIT的执行效率要高很多。
2》,当JIT需要再调用这些已经被编译好并存储到代码缓存中的方法时,它不用再去解释执行了,而是可以使用代码缓存中已编译好的汇编代码。这能提升你的应用程序的执行效率,因为使用编译好的代码要比运行时去解释要快得多。(PS:JIT将编译好的代码储存在GAC中)
三,GAC是什么?
1》GAC是Global Assembly Cache,全局程序集缓存的简称。它解决了几个程序共享某一个程序集的问题。不必再将那个被共享的程序集拷贝到应用程序目录了,.NET应用程序在加载的时候,会首先查看全局应用程序集缓存,如果有就可以直接使用,没有再到应用程序目录进行查找。
2》GAC还有一个很重要的作用,所有被放入GAC的程序集都是强名程序集,这样可以保证相同文件名不同版本的程序集被正确的引用,这样解决了COM时代的DLL地狱问题。同时强名还可以防止程序集伪造。
四,Assembly(程序集)是什么?
1》Assembly是一个包含来程序的名称,版本号,自我描述,文件关联关系和文件位置等信息的一个集合。在.net框架中通过Assembly类来支持,该类位于System.Reflection下,物理位置位于:mscorlib.dll。
2》我们可以通过Assembly的信息来获取程序的类,实例等编程需要用到的信息。
五,编译流程
六,托管程序集