子曾经曰过

  博客园  :: 首页  ::  ::  ::  :: 管理

1.1 源代码编译为托管代码

.NET框架的核心是通用语言运行时CLR,是一种可被各种不同的变成语言所使用的运行时。(什么是运行时?runtime?干吗用的?)

为什么说.NET是个框架,简单理解它支持多种语言在.NET下共同完成一个任务。能这样做的基础就是多种语言最后产生的是托管模块。

我们可以用任何支持CLR的语言来创建源代码,然后用相应编译器进行分析编译,最后生成一个托管模块。托管模块是一个需要CLR才能执行的标准的WINDOWS可移植可执行(PE)文件。这个1.1的图是不是显示的没有很完整?一个托管模块的组成部分由PE表头,CLR表头,元数据和IL(重金爱你语言)代码组成。下面简单说下各个部分的内容和作用:

PE表头:标准PE文件表头,(反解一个PE文件看看有什么内容),指出文件的类型是GUI(图形用户界面),CUI(控制台用户界面),还是DLL(这边的DLL和原来WINDOWS里的动态链接库DLL不是一回事,.NET中的DLL特指程序集文件的一种形式)。另外,表头还包含了一个时间标记表示文件创建的时间。对于仅仅包含IL代码的模块,该表头大部分信息会被忽略。对于包含有本地CPU代码的模块(什么事本地CPU代码模块?),该表头还会包含一些有关本地CPU代码的一些信息。

CLR表头:包含标识托管模块的一些信息(这些信息可以被CLR或者实用工具解析)。这些信息包括托管模块所需要的CLR版本号,一些标记,托管模块入口点方法(Main方法)的MethodDef元数据标记,以及有关托管模块的元数据,资源,强命名,标记和其他一些意义不大的信息的位置和尺寸。

元数据:每个托管模块都包含有一些元数据表。元数据表分两种,一种描述源代码中定义的类型和成员,一种描述源代码中引用的类型和成员。

IL代码:编译器在编译源代码时产生的指令(注意是一条条的指令)。CLR在运行时会将IL代码编程成本地CPU指令。

为什么叫托管代码?:大多数以前的编译器编译的代码是面向特定CPU的(比如X86等),而所有与CLR兼容的编译器产生的都是IL代码,由于生存期和执行行为受CLR管理的缘故,IL代码也被称作托管代码。也就是说IL是离不开CLR的,需要CLR这个托管环境。

除了产生IL外,CLR编译器都需要为托管模块产生完整的元数据(metadate)。元数据就是一个数据表的集合(如何排列分布的?)其中一些用于描述托管模块中定义的内容(如定义的类型和成员),另外还有一些用于描述所引用的内容(如引用类型和成员)。元数据是一些早先的技术如类型库,接口定义语言(IDL,vc++中有用到,COM,ACTIVEX,ATL等)文件的一个超集,而且比他们完整。元数据总是和包含IL代码的文件相关联(什么意思?)。元数据实际上总是和这些代码一起被嵌入到同一个EXE/DLL文件中,两者根本不可能分离。因为编译器总是同时产生元数据和IL代码,并且同时将他们嵌入到生成的托管模块中,所以元数据和它所描述的IL代码之间总保持同步。下面是元数据的一些用处介绍

<1>: 省去了编译时对头文件和库文件的需求,这是因为在含有实现类型和成员的IL代码文件中,已经包含了所有被引用的类型和成员的信息,编译器可以直接从托管代码中读取元数据来获得这些信息。

<2>:VS2008可以利用元数据来辅助我们编写代码,智能感应就是通过分析元数据告诉我们某类型提供了哪些方法,以及某个方法有哪些参数。

<3>:CLR利用元数据确保代码仅执行安全的操作

<4>:利用元数据,我们可以将一个对象的字段序列化到一个内存块中,然后远程传送给另一台机器,最后再在远程机器上执行反序列化,从而重新创建对象和它的状态(remoting,wse,ws,wcf等)。

<5>:利用元数据,CG垃圾收集器可以追踪对象的生存期。

支持CLR的编译器如C#编译器等和IL汇编器总是产生需要CLR才能执行的托管代码,所以用户必须安装CLR。这和我们需要安装MFC道理类似。

默认情况下,微软的C++便器生成的是非托管模块,传统的EXE/DLL等。它们执行不需要CLR,当然也可以产生托管的模块,需要指定编译开关。

 

 

posted on 2011-02-17 21:32  人的本质是什么?  阅读(338)  评论(0编辑  收藏  举报