元数据和 PE 文件结构

元数据存储在 .NET Framework 可迁移可执行文件 (PE) 文件的一个部分中,而 Microsoft 中间语言 (MSIL) 则存储在 PE 文件的另一部分中。 文件的元数据部分包含一系列的表和堆数据结构。 MSIL 部分包含 MSIL 和引用 PE 文件元数据部分的元数据标记。 当使用工具(例如,使用 MSIL 反汇编程序 (Ildasm.exe) 来查看代码的 MSIL)时,您可能会遇到元数据标记。

元数据表和堆

每个元数据表都保留有关程序元素的信息。 例如,一个元数据表说明代码中的类,另一个元数据表说明字段等。 如果您的代码中有 10 个类,类表将有 10 行,每行一类。 元数据表引用其他的表和堆。 例如,类的元数据表引用方法表。

元数据还以四种堆结构存储信息:字符串、Blob、用户字符串和 GUID。 所有用于对类型和成员进行命名的字符串都存储在字符串堆中。 例如,方法表不直接存储特定方法的名称,而是指向存储在字符串堆中的方法的名称。

元数据标记

元数据标记在 PE 文件的 MSIL 部分中唯一确定每个元数据表的每一行。 元数据标记在概念上和指针相似,永久驻留在 MSIL 中,引用特定的元数据表。

元数据标记是一个四个字节的数字。 最高位字节表示特定标记(方法、类型等)引用的元数据表。 剩下的三个字节指定与所说明的编程元素对应的元数据表中的行。 如果您用 C# 定义一个方法并将其编译到 PE 文件,下面的元数据标记可能存在于 PE 文件的 MSIL 部分:

 0x06000004

最高位字节 (0x06) 表示这是一个 MethodDef 标记。 低位的三个字节 (000004) 指示公共语言运行时在 MethodDef 表的第四行查找对该方法定义进行描述的信息。

PE 文件中的元数据

当为公共语言运行时编译程序时,该程序转换为由三部分组成的 PE 文件。 下表说明了每部分的内容。

PE 部分

PE 部分的内容

PE 标头

PE 文件主要部分的索引和入口点的地址。

运行时使用该信息确定该文件为 PE 文件并确定当将程序加载到内存时执行从何处开始。

MSIL 指令

组成代码的 Microsoft 中间语言指令 (MSIL)。 许多 MSIL 指令带有元数据标记。

元数据

元数据表和堆。 运行时使用该部分记录您的代码中每个类型和成员的信息。 本部分还包括自定义特性和安全性信息。

请参见

概念

元数据和自描述组件