CLR via C# FOURTH EDITION(一)将源代码编译成托管模块

Part 1 CLR 基础

Chapter 1 CLR的执行模型

这一章节的内容:

  1. 将源代码编译为托管模块 (Compiling Source Code into Managed Modules)
  2. 将托管模块合并为程序集 (Combining Managed Modules into Assemblied)
  3. 加载公共语言运行时 (Loading the Common Language Runtime)
  4. 执行程序集代码 (Executing Yout Assembly's Code)
  5. 本地代码生成工具:NGen.exe (The Native Code Generator Tool: NGen.exe)
  6. Framework 类库 (The Framework Class Library)
  7. 通用类型系统 (The Common Type System)
  8. 通用语言规范 (The Common Language Specification)
  9. 与非托管代码协同工作 (Interoperabillity with Unmanaged Code)
The Microsoft .NET Framework 介绍了许多概念,技术,和条款(*terms或者应该翻译为“术语”?).这一章节的目的是给你们一个关于我们是如何设计.NET Framework的概观,向你们介绍一些Framework包含的技术,并定义了一些今后会见到的条款(*terms)。我也会指导你将源代码生成一个程序或者一组可重新分配(*redistributable)的组件(文件)的过程,这些组件(文件)包含了类型(类[Class],结构体[Structures],等等)。最后向你解释你的程序是如何执行的。

将源代码编译成托管模块
       OK,所以你已经决定使用.NET Framework作为你的开发平台了。Great!你的第一步是要决定你想要生成什么类型的程序或者组件。我们假设你已经完成了这个小细节;一切都已经设计好了,规范已经写好了,你已经准备好开始开发了。

      现在你必须决定使用哪一种编程语言。这通常是个困难的任务,因为不同语言拥有不同的能力。举个例子,在非托管的C/C++中,你可以对系统进行非常低等级的操作(*low-level control of system)。可以完全按照自己想要的管理内存,如果你需要的话,你可以更方便的创建线程,等等。另一方面,Microsoft Visual Basic 6 允许你非常快速的创建UI程序,让你可以方便的使用它管理COM对象和数据库。

       公共语言运行时(The Common Language Runtime CLR)就像它的名字所说的,是一种可以被多种不同的编程语言使用的Runtime。CLR的核心功能(比如:内存管理、程序集加载、安全性、异常处理和线程同步)可以由任意面向CLR的编程语言使用(*这里的—period是什么意思)。比如说:CLR使用异常来报告错误,所以所有面向CLR的语言都可以通过异常来得到错误报告。再举个例子:CLR允许你创建进程,所有任意面向CLR的语言都可以创建进程。

        事实上,在运行时,CLR并不知道开发者用哪种语言编写的源代码。这就意味着,你可以选择一种可以最方便表达你意图的语言。你可以用任何语言开发你的代码只要你用来编译的编译器面向CLR。

所以,如果我说的是真的,那么一个语言比起其他语言的优势是什么呢?Well,我认为编译器就像是一个“语法检查器”和“正确代码分析器”。他们检查你的源代码,确保所有你写的都有意义,然后输出描述了你意图的代码。不同的编程语言允许你使用不同的语法开发(*#¥%……&*这不是废话??)。不要低估这个选择的价值。举例说:对于数学或金融程序,使用APL语法表达意图比起使用Perl语法要节省许多天的开发时间。

Microsoft创建了许多种面向CLR的语言编译器:C++/CLI、C#、Visual Basic、F#、Iron Python、Iron Ruby和Intermediate Language(中间语言[IL])汇编器。除了微软,一些其他的公司、大学和学院也开发了面向CLR的编译器。我知道的编译器针对这些语言:Ada、APL、Caml、COBOL、Eiffel、Forth、Fortran、Haskell、Lexico、LISP、LOGO、Lua、Mercury、ML、Mondrian、Oberon、Pascal、Perl、PHP、Prolog、RPG、Scheme、Smalltalk和Tcl/Tk。

图1-1展示了编译源代码文件的过程。如图,你可以用任何支持CLR的编程语言编写源代码文件。然后,你可以用对应的编译器检查语法和整理源代码。不管你用哪个编译器,结果都是生成托管模块。一个托管模块即是一个标准的PE32可移植执行文件(32-bit Microsoft Windows portable executable),或一个标准的PE32+可移植执行文件(64-bit Microsoft Windows portable executable),它们都需要CLR才能执行。By the way,托管程序集(managed assemblies)总是利用windows的数据执行保护(Data Execution Prevention,DEP)和地址空间布局随机化(Address Space Layout Randomization,ASLR);这两个功能可以提升整个系统的安全性。


表1-1 描述了托管模块的各个部分
组成部分:
PE32 或 PE32+头 

说明:
标准的Windows PE文件头,类似于公共对象文件格式(Common Object FileFormat,COFF)头。如果文件头使用PE32格式,文件就可以在32位或者64位版本的Windows上运行。如果头文件使用PE32+格式,文件就需要一个54位版本的Windows才能运行。这个头文件还指示了文件类型:GUI,CUI或DLL还包含了一个时间戳指示了文件生成的时间。对于只含有IL代码的模块,PE32或PE32+头文件内的大部分信息会被无视。对于包含本地CPU代码的模块,他的头文件包含了有关本地CPU代码的信息。(这有是什么废话!)

组成部分:
CLR头

说明;
包含让它成为托管模块的信息(由CLR和utilities[*实用??]解释)。这个头文件包括了CLR需求的版本,一些标志(flag),定义托管模块入口方法(entry point method,Main method)的元数据,和模块元数据的位置/大小,资源,强名称,一些标志,和其他一下没意思的东西。

组成部分:
元数据

说明:
每个托管模块都包含元数据表格。表格有两个主要的类型:一个表格描述了源代码中定义的类型和成员,另一个表格描述了源代码中引用的类型和成员。

组成部分:
IL 代码

说明:
这是编译器编译源代码生成的代码。在运行时,CLR把IL编译成了本地的CPU指令。

本地代码编译器(Native code compilers)生成的代码指向一个特殊的CPU架构,比如x86,x64,或者ARM。每个兼容CLR的编译器(CLR-compliant compilers)生成的都是IL代码(之后会在本章节中说跟多的关于IL的细节)。IL代码有时被简称为托管代码因为CLR管理了它的运行。
除了生成(emitting)IL,每个面向CLR的编译器会在每个托管模块中生成完整的IL代码。简单的说,元数据是一组数据表格,它描述了模块中定义了什么,比如类型和他们的成员。另外,元数据也有表格表明了托管模块的引用信息,比如导入的类型和他们的成员。元数据是一个较老的技术的超集(superset)比如COM的类库(COM’s Type Libraries )和接口定义语言(Interface Definition Language,IDL)文件。有一点很重要,CLR的元数据要更加完整。而且,不像类库和IDL(接口定义语言),元数据总是与包含IL代码的文件相关联。事实上,元数据总是嵌入有相同代码的EXE/DLL中,让他们不会分成两个。因为编译器同时生成元数据和代码并把他们绑定到托管模块中,所以元数据和他描述的IL代码永远是与另一个同步的。

元数据有许多用途。这是一部分用途:
  • 在编译时,元数据移除了对本地C/C++头文件和库文件的需求因为所有关于对类型/成员的引用信息都被包含在了IL文件中,该IL文件用来实现类型/成员。编译器可以直接从托管模块中读取元数据。
  • VS(Microsoft Visual Studio)使用元数据来帮助你写代码。他的智能感知功能通过解析元数据来告诉你一个类提供了什么方法、属性(properties)、事件、字段,至于方法,会告诉你方法需要的参数。
  • CLR的代码验证过程(code verification process)使用元数据来确保你的代码只执行"安全类型"的操作。(我之后会简短的讨论验证。)
  • 元数据允许将一个对象的字段序列化到一个内存模块中,传到另一个机器中,然后在远处机器上反序列化重建对象的状态。
  • 元数据允许垃圾收集器追踪对象的生命周期。垃圾收集器能确定对象的类型,通过元数据,能知道对象的哪些字段引用自其它对象。
在第2章,”生成,打包,部署,和管理程序和类型“中,我会说到更多的元数据的细节。

微软的C#,VB(Visual Basic),F#和IL汇编器总是生成包含托管代码(IL)和托管数据(垃圾收集数据类型[garbage-collected data types])的模块。最后用户必须有CLR(现在是.NET Framework的一部分)安装他们的电脑上才能执行任何包含了托管代码和托管数据的模块,这就像有MFC(Microsoft Foundation Class )库或者VB(Visual Basic)DLLs才能运行MFC或者VB6 应用程序。

默认的,在运行时,微软的C++编译器生成EXE/DLL模块包含了非托管(本地)代码和操作非托管数据(本地内存)。这些模块不需要CLR来执行。然而,使用/CLR命令行开关,C++编译器会生成包含托管代码的模块,当然,CLR必须被安装来运行这些代码。所有提到的微软编译器中,C++是独一无二的,它是唯一一个编译器允许开发者既可以写托管代码也可以写非托管代码,并把它们放到一个模块中。它也是唯一一个微软的编译器允许开发者在源代码中定义托管和非托管数据类型。微软的C++编译器提供的灵活性是其他编译器无法比拟的,因为他允许开发者在托管代码中使用它们现有的本地C/C++代码,使他们开始习惯使用托管类型。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值