在
.NET 出现之前, Windows 的程序有一些非常困扰人的问题:
1.当安装一个新的应用程序,有些时候会发现,它莫名其妙地损坏了已安装的应用程序
(事实上是在系统的
Win32 文件夹内添加了与之前重名的 dll 文件,导致该 dll 被覆盖)。这
种困境被称大家称为
“DLL 灾难”。
2.大部分的程序安装会影响到所有的系统部件。比如:要在不同的位置拷贝文件,要在注册
表中添加信息。这个问题在于不能将应用程序作为一个单一的实体,这同时也导致了程序不
便于拷贝
/备份/部署。
3.安全问题。我们很难去保证程序的运行不会危害用户。
.NET 程 序 提 出 的程 序 集 ( Assembly) 概 念很 好 的 解决 了
“DLL 灾难”和部署难的问
题,并且也提供一些安全保障。下面就让我们来谈谈程序集, 程序集并不是一个单一
的 物 理 单 位 , 它 是 由 一 个 或 者 多 个
包 含 元 数 据 ( Metadata ) 的 托 管 模 块 ( Managed
Module)、一些资源文件 以及 清单 逻辑组成。
一、托管模块(
exe/dll)的相关概念
托管模块一般以
.exe/.dll 的形式出现,它们由面向 CLR 的编译器生成。它主要包含以下四个
部分:
1、PE32/PE32+ header 。标准 windows PE 头文件,主要指定了 该模块是 32 还是 64 位文件。
还指定了给模块是
GUI(exe),CUI(exe)或者 DLL 其中的一种。
2、CLR header。CLR header 的定义在 CorHdr.h 文件中。它主要包含 CLR 版本、模块入口函数
(
Main 函数)的 MethodDef 元数据、元数据的大小及偏移量、可选的强签名。
3、Metadata。元数据是以二进制数据组成的块(a block of binary data)。它中包含 3 类表,
分别是:定义表(
definition tables)、引用表(reference tables)、清单表(manifest tables)。
由于元数据提供如此完备的信息,使得程序集具有自描述的功能,从而解决了博客开头的
前两个问题。
·定义表(definition tables) 包含本模块内定义的 类型,方法,字段,参数,属性,事
件。
·引用表(reference tables) 包含了本模块所引用的 数据集,模块,类型,方法,字段
属性,事件。
·清单表(manifest tables) 是描述整个程序集的表。它包含了程序集中所有文件的名称
以及程序集的版本、文化、出版者、公开导出的类型。