您的位置:首页 > 编程语言 > C#

CLR via C# 读书笔记1-1

2013-04-28 10:52 183 查看
CLR via C# 读书笔记1-1

把源代码编译为托管模块 (Managed Modules)

进行开发之前,你首先需要选择你擅长的语言。某些时候这很难抉择,因为不同的开发语言提供不同的开发特性。例如:非托管 C/C++ 提供了操作系统非常底层的控制权,你能够随心所欲地管理内存,轻而易举地建立线程,等等。 相反的 Microsoft Visual Basic 6.0 让你能快速的开发 UI 界面程序,而且提供了简便的使用 COM 对象以及数据库的方法。

common language runtime (CLR) 就如它的字面含义:一个被许多不同开发语言所使用的运行时。他的主要特性 (内存管理, 程序集载入, 安全, 异常处理, 以及线程同步) 在他对应的所有开发语言中被支持。举例来说,这个运行时使用异常来报告错误,所以所有这个运行时对应的开发语言都能通过异常来得到错误报告。再举一个例子:这个运行时允许建立线程,所以所有这个运行时对应的开发语言都能建立线程。

事实上,在运行的时候 CLR 并不知晓程序使用了那种开发语言。这意味着你可以选择任何你擅长的语言(只要是CLR支持的语言)。那么不同的语言之间还存在优势/劣势吗?我觉得编译器就像一个语法检查器,它检查你的源代码,确认你想做的,然后输出。不同的语言采用不同的语法,而不同的语法通常有其针对性,有些善于数学公式,有些善于线程同步...,你可以根据实际情况选择适合的语言。

微软已经建立了几个语言(C++/CLI, C#, Visual Basic, F#, Iron Python, Iron Ruby, 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.



如插图所示,使用这些编译器进行处理后,用不同开发语言写成的源代码都会被输出成托管模块 (managed module)。托管模块 (managed module)是一个标准的32/64位 Windows 可执行文件(PE32 / PE32+),当然它运行在 CLR 上。顺便说下:托管模块 (managed module)在Windows系统上总是具备 Data Execution Prevention (DEP) 以及 Address Space Layout Randomization (ASLR)
特性,这两个特性提升了整个系统的安全性。

托管模块(Managed Module)的组成

组成说明
PE32 / PE32+ 头标准的 Windows PE 头文件与 Common Object File Format (COFF) 头文件非常类似。使用了PE32 格式的头信息使得这个文件能在 32 / 64 位的 Windows 中运行,如果头信息是 PE32+ 格式,那么这个文件只能运行在 64 位的 Windows 上。这个头信息还表明了当前文件的类型: GUI, CUI, 或者 DLL,另外还包含了一个时间戳(表明何时被编译)。 对于只包含了 IL 代码的模块,用来存储 PE32(+) 头信息的空间将被省略。对于只包含了本地
CPU 代码的模块,头信息只包含本地 CPU 代码的信息。
CLR 头这些信息(被 CLR 解释执行)指示当前文件是个托管模块,头信息包含了需要的 CLR 版本信息,一些标志量,模块入口(Main 方法) 的 MethodDef 元数据 (metadata) ,以及模块元数据 (metadata) 的地址和大小, 资源,强命名,等等。
元数据(Metadata)每个托管模块都包含元数据(Metadata)表,这些表有两种主要类型:. There are two main types of tables:

一种用来描述源代码中的类型和成员,一种用来描述被你源代码参照引用的类型和成员
IL代码源代码被编译器编译后的产物。在运行的时候 CLR 编译器把这些 IL 代码转换成本地 CPU 指令
本地代码 (Native code) 编译器总是生成针对某一特定 CPU 构架的代码,例如 x86, x64, 或 ARM。而所有 CLR 兼容编译器生成 IL 代码。 IL 代码总是被称为托管代码,因为他的执行由 CLR 全权管理。

除了 IL 之外,针对 CLR 的编译器还需要把完整的元数据(metadata) 写入到托管模块 (managed module) 中,简要地来说元数据(metadata)是一组数据表,描述了“这个模块中定义了什么,什么类型阿,成员阿”。另外元数据(metadata)还记录了该模块的参照信息,包括参照类型以及它们的成员。元数据(metadata)可算作一些老技术(COM’s Type Libraries 以及 Interface Definition Language (IDL) 文件)的超集。这里需要注意的是
CLR 元数据(metadata) 本身并不完整,所以不像 Type Libraries 或 IDL一样,它总是与包含了IL代码的文件关联在一起,总是被包含在同一个EXE/DLL文件中(无法分割)。因为编译器同时生成元数据(metadata)和代码并把它们一起写入托管模块 (managed module),所以元数据(metadata)和IL代码彼此之间总是同步的。元数据(metadata)有许多应用场景,以下是经常遇到的:

■ 元数据(metadata)使得在编译时不再需要本地(native) C/C++ 头文件和库文件,因为所有的参照信息都已经包含在同一个文件中,编译器可以从托管模块 (managed module)中直接读取到

■ Microsoft Visual Studio 使用元数据(metadata)来帮助你编写代码。 IntelliSense 机能解析元数据(metadata)来告诉你某一个类型的成员方法,属性,事件,字段等等,或者罗列出某一个方法接受的参数

■ CLR 的代码检查处理会使用这些元数据来确保你的代码都是类型安全(type-safe)的。

■ 元数据使得对象的字段能够被序列化到内存块中,传送给另一台机器,并在该远程机上反序列化,重新构建该对象的状态

■ 元数据帮助垃圾回收器 (garbage collector) 来监视对象的生存期,垃圾回收器通过元数据可以获取对象的类型,并且获知哪些字段参照了其他的对象

Chapter 2, “Building, Packaging, Deploying, and Administering Applications and Types,”中会更详细的介绍元数据。

Microsoft 的 C#, Visual Basic, F#, 以及 IL Assembler 总是生成包含托管代码(IL) 以及托管数据 (garbage-collected 数据类型)的模块,终端用户也就必须在安装了 CLR

(包含在 .NET Framework 安装包中) 的机器上执行这些模块。这就好像你必须分别安装 Microsoft Foundation Class (MFC) 类库 或 Visual Basic 类库来运行 MFC 或 Visual Basic 6.0 程序一样。

缺省情况下 Microsoft 的 C++ 编译器把 EXE/DLL 模块编译成非托管(本地)代码,在其运行的时候对非托管的数据(本地内存)进行操作,这些模块的执行不需要CLR。 但是你可以在编译的命令行中追加 /CLR 开关量,C++ 编译器将生成包含托管代码的模块,这是它的执行将依赖 CLR。根据所有 Microsoft 编译器的描述,C++ 是唯一一个允许开发者在同一模块中同时包含托管与非托管代码的编译器,也是唯一一个允许在源代码中同时定义托管与非托管源代码的编译器。Microsoft 的 C++ 编译器提供的灵活性是独一无二的,它允许你在任何你觉得合适的场合在托管代码中使用既有的本地
C/C++ 代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: