第一章 Microsoft .NET框架开发平台体系结构[《.net框架程序设计》读书笔记]

** 第一章 ?? ** ** Microsoft .NET ** ** 框架开发平台体系结构 **

** 一、 ???????????? ** ** 将源代码编译为托管模块: **

?

1、 ? CLR 的存在是得我们可以选择适合表达逻辑的语言,只要存在相应得编译器将代码编译成为面向 CLR 的代码即可,结果成为托管模块。

?

2、 ? 托管模块( managed module ):是一个需要 CLR 才能执行的标准 windows 可移植可执行文件 (portable executable : PE) ,组成:

  1. ??????? PE 表头:指出文件类型,文件的时间标记

  2. ??????? CLR 表头: CLR 版本,托管模块入口、元数据、资源、强命名、标记等信息

  3. ??????? 元数据:源代码中定义、引用的类型和成员

  4. ??????? 中间语言( IL )代码

关于元数据:

l ???????? 总与 IL 代码同步

l ???????? 省去源代码编译时对头文件和库文件的需求

l ???????? Visual Studio .NET 利用之进行智能感知,辅助编码

l ???????? 用于 CLR 的代码验证

l ???????? 序列化及反序列化对象

l ???????? 垃圾收集器可以追踪对象的生存期

** ? **

** 二、 ???????????? ** ** 将托管模块组合为程序集 **

关于程序集的理解: 暂歇

三、 加载通用语言运行时

1、 ? 通过在 %window%\system32 目录下查找 MSCorEE.dll 文件来判断一个机器中是否安装了 .NET 框架;而框架的版本可从注册表下的子键:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ .NETFramework \ policy 中查看

2 、 当生成一个 EXE 程序集时,编译器/链接器会产生一些特殊的信息,并将它们嵌入到结果程序集的 PE 文件表头及其各个组成文件的 .text 部分。当 EXE 文件被调用时,这些特殊的信息将导致 CLR 被加载并初始化。 CLR 随后会定位至应胜程序的入口点方法,从面以此来启动应用程序。

?

类似地,如果是一个非托管应用程序通过调用 LoadLibrary 来加载一个托管程序集,那么该托管程序集 DLL 的入口点函数也会知道去加载 CLR 来处理包含在其中的代码

3、 ? 其他诸如 EXE 程序集或 DLL 程序集如何被执行的过程,可在考察普通 Windows PE 文件的执行过程后进行比较以明确执行过程

四、 执行程序集代码

1、 ? IL 代码:一种面向对象的机器语言。可以理解对象类型,包含高级指令:创建和初始化对象、调用对象上的虚方法、直接操作数组元素、抛出和捕获异常;

IL 汇编语言能获取 CLR 的所有功能,其他高级语言智能获取其中的一个子集;

IL 代码独立于 CPU 平台,执行时要先被即时编译器 (Just In Time Compiler) 编译;

微软提供的 IL 汇编器: ILAsm.exe 反汇编器: ILDasm.exe 。

?

2、 ? IL 代码执行过程:

以下面代码段为例:

??????? static void Main ()

??????? {

?????????????? Console.WriteLine(“Hello”);

?????????????? Console.WriteLine(“GoolBye”);

}

? 0 )代码被执行之前:

???? CLR 首先检测 Main 中代码所引用到的所有类型,并分配一个数据结构记录该类型,数据结构为类型的每个方法分配一个对应条目,记录该方法实现代码的地址;初始化该结构时,各方法被设置为 CLR 内部的一个函数(未定义的函数)

  1. ??????? 第一次被执行时

当上述结构中某函数被调用时, JITComplier 由该函数的类型及地址信息在程序集的元数据中找到其 IL 代码的位置,把这些 IL 代码验证并编译成本地 CPU 指令这些 CPU 指令被保存在一个动态分配的内存中,而 a) 步骤中数据结构中被调用方法的地址则被替换为包含本地 CPU 指令的地址。

  1. ??????? 第二次被执行时

若被调用的函数已经被验证并编译过,则直接从内存中调用之

若没有被调用则重复第一次被执行时的情况

3、 ? 性能

托管代码可能比非托管代码效率更好的理由:

l ???????? JIT 编译器可检测到新型 CPU 并产生为这些 CPU 提供的特殊指令,以优化执行效率

l ???????? JIT 编译器可检测到总是返回错误的布尔测试,对于其所办函的代码段不产生 CPU 指令,以使得代码量更小,执行效率更高。

l ???????? CLR 在运行时有针对性地重新编译某些 IL 代码,重新组织以提高分支预测的成功率。

4、 ? NGen.exe 提供折中方案,为 IL 代码提供预编译版本,以避免运行时编译。

5、 ? IL 代码验证:

-- 被验证为“不安全”的代码将抛出 System.Security.VerificationException 异常

-- 代码验证使得可以在一个 windows 进程中可以运行多个 托管应用程序

更多的讨论在 20 章

五、 .NET 框架类库 (FCL)

CLR 和 FCL 允许开发人员创建以下几种应用程序:

l ???????? XML Web 服务

l ???????? Web 窗体

l ???????? Windows 窗体

l ???????? Windows 控制台应用程序

l ???????? Window 服务

l ???????? 组件库

制作特定的应用程序,关键是对相应得 FCL 的熟悉,那么首先对 .NET Framework 熟悉了吧。

六、 通用类型系统( Common Type System )

描述了 CLR 中类型的规范

类型的成员组成:

l ???????? 字段:表明对象的状态

l ???????? 方法:用来改变状态

l ???????? 属性:提供对状态访问时输入参数验证、状态有效性检验及必要的求值运算等功能

l ???????? 事件:对象间的通知机制

类型可见性和访问类型成员的一些规则:

l ???????? Private :只能被同一类型中的代码访问

l ???????? Family :可以被派生类中的代码调用,而不管是否位于同一个程序集中

l ???????? Family 与 Assembly :只能被位于同一个程序集中的派生类代码调用

l ???????? Assembly :只能被同一个程序集中的代码调用

l ???????? Family 或 Assembly :能被任何程序集中的派生类代码调用,也可以被同一程序集中的任何类型调用

l ???????? Public :可被任何程序集中的任何代码调用

七、 通用语言规范( Common Language Specification )

为使一种语言创建的类型能被其他语言无缝访问,微软定义了通用语言规范( CLS )。 CLR/CTS 支持的特性比 CLS 定义的丰富得多,实际上不同的语言实现了 CLR/CTS 特性的一个子集,而 CLS 则是所有语言特性的交集(一个最小特性集合)。

因此只有遵循 CLS 的类型才能被其他语言访问、应用, C# 中使用:

[assembly:CLSCompliant(true)]

迫使编译器确保在公共导出类型中,剔除不符合 CLS 的部分。

八、 与非托管代码互操作

为避免重新实现所有现有代码, CLR 被设计成包含托管部分和非托管部分, CLR 支持三种互操作情形:

l ???????? 托管代码调用 DLL 中的非托管函数

l ???????? 托管代码使用现存的 COM 组件

l ???????? 非托管代码使用托管类型

?

Published At
Categories with Web编程
Tagged with
comments powered by Disqus