内容提要
本章的目的是对.Net 框架的设计做一个总体的介绍,包括介绍框架中使用的一些技术、定义一些术语。同时会展示从源代码生成应用程序(或者一些包含了一些自定义类型的可以发布的组件),并且会解释程序的运行机制。
包含以下子标题:
- 将源代码编译成托管的模块(Managed Modules)
- 将Managed Modules 组合成 Assemblie
- 加载 CLR
- 执行 Assembly 代码
- Native code 生成工具:NGen.exe
- .NET 框架类库 (Framework Class Library, FCL)
- The Common Type System (CTS)
- The Common Language Specification (CTS)
- 与非托管代码的互操作性
将源代码编译成托管模块(Managed Modules)
CLR是可以被不同的编程语言共同使用的运行时环境。实际上,在运行时,CLR并不知道程序是使用什么语言写的,因为这些语言都被预先编译成了Managed Module (IL 和 元数据)。不同语言的编译器,可以认为是不同的代码检查器,检查代码的语法是否正确,描述的操作是否合理等。
本地代码产生针对CPU的代码,而C#、F#等语言产生的是针对CLR的代码。
除了产生IL代码之外,所有针对CLR的编译器还会在每个托管模块中生成"元数据"(metadata)。简要来说,Metadata是用来描述module中定义了什么东西(例如类型以及类型的成员)的一组数据表。另外,Metadata还描述了Module中引用了哪些东西(比如外部载入的类型以及类型的成员)
PE32 or PE32+ header |
|
CLR header |
|
元数据(Metadata) |
|
IL代码 |
|
Metadata有很多用途,例如:
- 有了Metadata就不需要像C/C++头文件以及库文件的东西了,因为Metadata将引用模块所需要的信息存储在模块自身当中了,编译器可以从模块中之间提取这部分信息;
- Visual Studio中的智能输入提示也是通过处理Metadata中所包含的信息来帮助写代码的;
- CLR的代码验证过程使用Metadata来确保只进行了类型安全的操作;
- 实现序列化
- 是的垃圾回收器可以确定对象的生命周期,对任意对象,gc可以通过metadata知道这个对象的类型以及这个对象引用了哪些其他对象;
C#/F#/ILAsm 都是产生托管的代码和托管的类型。而Microsoft C++则默认产生native code,但是可以通过/clr 使其产生托管的module。Microsoft C++还是唯一一个可以允许开发这既使用托管代码又使用非托管代码并且将二者注入到同一个module中的编译器,所以常被利用来在托管项目中调用已有的非托管代码。
将Managed Modules 组合成 Assemblie