13 第一部分 .NET 平台
表:
ModuleDef,这个表只保存一项,即当前模块的定义。该项包含一个带扩展名的文件名,但
不包括路径。
TypeDef,该表为模块中定义的每一个类型保存一个项。每一项都包含类型的名称、基类型、
类 型 的 标 志 (
public
、
internal
、
sealed
等 ) 以 及 该 类 型 成 员 在
MethodDef、FieldDef、ProperyDef、EventDef等元数据表中的索引。
MethodDef,该表为模块中定义的每一个方法都保存一个项。每一项都包含方法的名称、标
志(
public
、
abstract
、
sealed
等)、一个指出方法在IL代码中的位置的偏移量以及一个指向
方法签名的引用,方法签名按照一种二进制格式保存在一个名为 #blob的堆中,我们稍候将对
此进行讨论。
此外还有一个用于保存字段的表(FieldDef)、一个保存属性的表( PropertyDef)和一个保存
事件的表(EventDef)等。这些表的定义是标准的,而且每个表都使用一个唯一字节来编号。比
如.NET中所有的MethodDef表都有一个表编号6。
2. 引用表
引用表包含模块所引用的元素的信息。引用元素可能定义在同一程序集的其他模块中,也可能
作为其他程序集的一部分。下面是几种常用的引用表:
AssemblyRef,该表为本模块所引用的每一个程序集保存一个项(本模块所引用的程序集是指
每个至少包含一个被本模块所引用的元素的程序集)。每一项都包含组成强名称的 4个组成
部分:程序集的名称(不带路径或扩展名)、版本号、区域设置和公钥记号( public key
token)(如果没有的话是空值)。
ModuleRef,该表为本模块所引用的当前程序集的每一个模块保存一个项(那每个模块至少
包含一个被本模块所引用的元素)。每一项都包含模块的名称及其扩展名。
TypeRef,该表为本模块引用的每一个类型保存一个项。每一项包含类型的名称和一个类型位
置的引用。如果类型就定义在当前模块或者同一个程序集的其他模块中,这个位置引用就会
指向ModuleRef表的一个项。如果该类型定义在其他程序集中,这个位置引用就会指向
AssemblyRef表的一个项。如果该类型嵌套在另一个类型中,这个位置引用就会指向TypeRef
表的一个项。
MemberRef,这个表为本模块引用的每一个成员保存一个项。成员可以是一个方法、字段或
者属性。每一项都包含该成员的名称、签名以及一个TypeRef表的引用。
这些引用表的定义也符合标准,并使用一个字节来编号。比如所有 .NET模块的MemberRef表均
用数字10来标识。
3. 指针表
编译器可以使用指针表来引用未知的代码(有点像C++中的声明)。只要改变代码中元素声明的
顺序,就可以减少指针表的内容。这里我们列出几种指针表:MethodPtr、ParamPtr和FieldPtr。
4. 堆
除了这几种表,元数据段还包括4种堆,分别称作#Strings、#Blob、#US和#GUID。
#Strings堆用于保存字符串,比如方法的名字。这就是说诸如MethodDef或MemberDef这样的
表并不包含实际的字符串,只是引用#String堆的元素。
#Blob堆用于保存二进制信息,如方法签名的二进制格式。这就是说MethodDef或MemberDef
的元素并不包含签名本身,而是引用#Blob堆。
#US(User String)堆包含直接定义在代码中的字符串。
评论0
最新资源