一个程序集可以定义成为在一个文件夹下的由N个(N>=1)模块文件和资源文件组成的逻辑单元,其内部必定含有且仅有一个后缀为.exe或者.dll的主模块文件,可能包含后缀为.netmodule的非主模块文件,但是由于在VS下无法生成多模块程序集,所以我们当前见到的大部分都是单主模块程序集。这里讲的资源文件指的是不包含在模块内的,以独立的文件形式(JPG、GIF、XML)存在的并被程序集引用的文件。
程序集是由模块组成的,模块作为独立存在的物理单元,其结构是怎样的呢?
PE文件头 | CLR文件头 | 清单 | 元数据 | IL代码 | 资源 |
主模块结构表(非主模块没有清单外结构与主模块类似)
1、PE文件头:PE(Protable Executable)是Windows操作系统的可执行文件,模块作为一个PE文件,类似的有一个PE文件头用来存放最低可运行的Windows版本号等信息
2、CLR文件头:包含编译该模块时采用的的CLR的版本信息以及指向托管应用程序入口的引用。
3、清单:manifest,主模块所特有的结构,其中包含了对整个程序集的描述,由4部分组成:
(1)、AssemblyDef:描述程序集整体信息(名称(不包含扩展名和路径)、版本、区域设置、描述程序集特征的标志、一个散列算法引用、发行者的公钥(可为空));
(2)、FileDef:描述程序集内除主模块外其他所有非主模块和资源文件:文件名(包含扩展名)、描述文件属性的标志、文件散列值;
(3)、ManifestResourceDef:描程序集内每一个资源,名称、所在的模块在FileDef中的索引,资源如果是内嵌的还会特殊表明在其模块文件中的物理存储位置偏移量。从这里可以看出,每次重新编译任何一个模块都要重新编译ManifestResourceDef,所以就要重新编译主模块。
(4)、ExportTypeDef:为每个在程序集外可见的程序集内的类型(除主模块内的程序集外可见类型)存储一个项,每个项包含类型名称、所在的模块在FileDef表中的索引,及类型在其所在模块文件中的物理存储位置偏移量。这个地方有个问题,现在这种登记方式,ExportTypeDef的内容是ManifestResourceDef的部分重复登记,为什么ExportTypeDef不简单的保存类型名称及在ManifestResourceDef中该类型的索引呢?自我感觉可能是出于效率的原因吧。谁帮我解答一下!thanks!