文档章节

clr 元数据

drv
 drv
发布于 2016/12/28 11:31
字数 1300
阅读 4
收藏 0

  clr相关编译器编译生成的托管模块由四部分组成:PE32或32+头、clr头、元数据、IL代码。

  元数据和IL代码完全对应,保持一致(:>)性。

  元数据有很多用途

    VS的智能感知,自动补全;

    代码验证保证类型安全;

    序列化、反序列化;

    垃圾回收(从元数据得知哪些根引用了对象)。

  元数据包含两类表,一种描述源代码中定义的类型和成员;另一种描述代码引用的类型和成员。模块内部的一些元数据表的大小和偏移量在clr头中会有包含。

  元数据是由几个表构成的二进制数据块。有三种表:定义表、引用表、清单表。

  常用元数据定义表(定义于模块中的):

    ModuleDef : 一个记录项。包含模块名、扩展名和模块版本ID(编译器创建的GUID);

    TypeDef : 每个类型一个记录项。包含类型名称、基类型、一些标志(public,private等)以及一些索引(指向MethodDef表中该类型的方法、FieldDef表中该类型的字段、PropertyDef表中该类型的属性以及EventDef表中该类型的事件);

    MethodDef : 每个方法一个记录项。包含方法的名称、一些标志(private,public,virtual,abstract,static,final等)、签名以及方法的IL代码在模块中的偏移量。每个记录项还引用了ParamDef表中的记录项;

    FieldDef : 每个字段一个记录项。包含标志(public,private等)、类型和名称;

    ParamDef : 每个参数一个记录项。包含标志(in,out,retval等)、类型和名称;

    PropertyDef : 每个属性一个记录项。包含标志、类型和名称。

    EventDef : 每个事件一个记录项。包含标志和名称。

 

      ModuleDef  {1}----------->{*} TypeDef {1}-----------------> | {*} MethodDef {1} ----------------->{*} ParamDef

                                      | {*} FieldDef

                                      | {*} PropertyDef

                                      | {*} EventDef

 

  常用引用源数据表

    AssemblyRef : 引用的每一个程序集有一个记录项。包含绑定该程序集所需的信息:程序集名称、版本号、语言文化以及公钥Token(根据发布者的公钥生成的一个小的哈希值,标识了所引用程序集的发布者)。另外还包含了一些标志以及一个被CLR忽略的但可以用于程序集的二进制数据的校验和的哈希值。

    ModuleRef : 引用类型的实现的每个PE模块有一个记录项。包含模块名和扩展名。

    TypeRef : 每个引用的类型有一个记录项。包含类型的名称和引用(指向类型的位置)。如果类型在另一个类型中实现,引用指向一个TypeRef记录项。如果类型在同一模块中实现,引用指向一个ModuleDef记录项。如果类型在调用程序集内的另一个模块中实现,引用指向一个ModuleRef记录项。如果类型在不同的程序集中实现,引用指向一个Assembly记录项;

    MemberRef : 引用的每个成员(字段、方法、属性方法和事件方法)有一个记录项。包含成员的名称和签名,并指向对成员进行定义的类型的TypeRef记录项。

      

      MemberRef------------->TypeRef-----------------> | TypeRef        (在另一个类型中实现)        ======>ModuleDef 或 ModuleRef 或 Assembly 

                                  | ModuleDef  (在同一模块)

                                  | ModuleRef    (在同程序集的不同模块)

                                  | Assembly     (在不同程序集)

 

  除此之外还有很多定义表和引用表。

  清单表中主要包含作为程序集组成部分的那些文件的名称。此外,还描述了程序集的版本、语言文化、发布者、公开导出的类型以及构成程序集的所有文件。

  CLR总是首先加载包含“清单”元数据表的文件,再根据“清单”来获取程序集中的其他文件。清单包含在PE文件中。

  清单元数据表(程序集的):

    AssemblyDef : 如果模块标识的是程序集,就包含单一记录项来列出程序集名称、版本、语言文化、一些标志、哈希算法以及发布者公钥(可为null);

    FileDef : 每个PE文件和资源文件都有一个记录项(清单本身所在文件除外,该文件在AssemblyDef的单一记录项中列出)。包含文件名、扩展名、哈希值和一些标志。如果程序集只包含自己的文件,则该表无记录(VS中不能创建多文件程序集,只能通过命令行);

    ManifestResourceDef : 每个资源文件一个记录项。包含资源名称、一些标志(是否外部可见:public,private)以及FileDef表的一个索引(指出包含在哪个文件中)。如果资源不是独立文件,那么资源是包含在PE文件中的流。嵌入资源,记录项会包含一个偏移量,指出资源流在PE文件中的起始位置;

    ExportedTypesDef : PE模块中导出的每个public类型有一个记录项。包含类型名称、FileDef表的一个索引(指出类型由程序集的哪个文件实现)以及TypeDef表的一个索引。

 

      AssemblyDef {1}-------------------->{*} FileDef {1}<----------------------------->{1} ManifestResourceDef

      ExportedTypesDef {0,1}------------>{1} FileDef + {1} TypeDef

      

  

© 著作权归作者所有

drv

drv

粉丝 2
博文 57
码字总数 75382
作品 0
东城
架构师
私信 提问
CLR执行模型

前言 《CLR via C#》(Jeffrey Richter著)——.NET 界的经典之作,相读"恨晚",读的过程写点笔记跟大家分享: 【我也推荐大家看英文版,能够直接领会原意 】 认识CLR 一 个被多种编程语言使用的...

mszhangxuefei
2012/07/06
0
0
CLR via C#:.NET平台下代码怎么跑起来

  【IT168技术】想起前些日子去某知名电子商务公司面试的时候,问了很多我.NET程序的运行机制,当时很多比较底层的问题都没答好,发现自己的知识太皮毛了。于是决定好好学习。今天看的是代...

博客
2011/12/22
0
0
微软将编译器通用基础结构开源了

【IT168 资讯】微软研究院已经将“Common Compiler Infrastructure: Metadata (CCI)”和“CCI: Code and AST”两个项目开源了,其中包含了一套让编译器或编程工具操作CLR程序集元数据和调试文...

IT168网站
2009/04/20
0
0
跟小静读CLR via C#(01)-.NET平台下代码是怎么跑起来的

跟小静读CLR via C#(01)-.NET平台下代码是怎么跑起来的 想起前些日子去某知名电子商务公司面试的时候,问了很多我.NET程序的运行机制,当时很多比较底层的问题都没答好,发现自己的知识太皮...

技术小胖子
2017/11/08
0
0
标识是什么?

标识就是指针,标识就是引用,标识就是节点内部用来识别区分本节点内的结构体的记号。所有的引用都只是节点内的引用,具体的引用类型被定义在的那个节点就是它的边界。所有的引用类型当被传出...

anycmd
2014/10/23
150
0

没有更多内容

加载失败,请刷新页面

加载更多

前端技术之:Prisma Demo服务部署过程记录

安装前提条件: 1、已经安装了docker运行环境 2、以下命令执行记录发生在MackBook环境 3、已经安装了PostgreSQL(我使用的是11版本) 4、Node开发运行环境可以正常工作 首先需要通过Node包管...

popgis
今天
5
0
数组和链表

数组 链表 技巧一:掌握链表,想轻松写出正确的链表代码,需要理解指针获引用的含义: 对指针的理解,记住下面的这句话就可以了: 将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指...

code-ortaerc
今天
4
0
栈-链式(c/c++实现)

上次说“栈是在线性表演变而来的,线性表很自由,想往哪里插数据就往哪里插数据,想删哪数据就删哪数据...。但给线性表一些限制呢,就没那么自由了,把线性表的三边封起来就变成了栈,栈只能...

白客C
今天
43
0
Mybatis Plus service

/** * @author beth * @data 2019-10-20 23:34 */@RunWith(SpringRunner.class)@SpringBootTestpublic class ServiceTest { @Autowired private IUserInfoService iUserInfoS......

一个yuanbeth
今天
5
0
php7-internal 7 zval的操作

## 7.7 zval的操作 扩展中经常会用到各种类型的zval,PHP提供了很多宏用于不同类型zval的操作,尽管我们也可以自己操作zval,但这并不是一个好习惯,因为zval有很多其它用途的标识,如果自己...

冻结not
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部