一、源代码-面向CLR的编译器-托管模块-(元数据&IL代码)
本文脉络图如下:

1、CLR(Common Language Runtime)公共语言运行时简介

(1)、公共语言运行时是一种可由多种编程语言一起使用的"运行时".
(2)、CLR的核心功能可由面向CLR的所有语言使用,例如:"运行时"使用异常来报告错误,因此面向CLR的所有语言都使用异常来报告错误.另外,CLR允许创建线程,所以所有面向CLR的编程语言都允许创建线程.
(3)、运行时,CLR并不关心程序使用的是哪种语言,只要该语言是面向CLR的就行.
2、面向CLR的语言编译器

3、面向CLR的语言编译器编译源代码的过程

我们可以使用任何面向CLR的语言创建源文件,然后用对应的编译器去检查语法和源代码,无论选择哪个编译器,通过编译器编译后生成的都是托管模块((IL)中间语言和元数据的组合).
本地代码编译器(native code compilers)生成的是面向特定CPU架构(比如X86、X64、ARM)的代码。相反,面向CLR的每个编译器生成的都是IL(中间语言)代码(IL代码有时被称为托管代码,因为CLR管理它们的执行),除了生成IL(中间语言),面向CLR的每个托管模块中生成完整的元数据.
(1)、托管模块
托管模块简介
标准的32位Microsoft Windows可移植执行体(PE32)文件
标准的64位Microsoft Windows可移植执行体(PE32+)文件
它们都需要CLR才能执行.
注:托管模块总是利用Windows的数据执行保护(Data Execution Prevention,DEP)和地址空间布局随机化(Adress Space Layout Ramdomization),这两个功能旨在增强整个系统的安全性.
托管模块构成

PE32或PE32+头:标准Windows PE文件头,类似于"公共文件对象格式"(Common Object Format,COFF)头。
注:如果文件头使用PE32格式,文件能在Windows的32位版本和64位版本上运行,如果文件头是PE32+格式,那么该文件只能在Windows64位版本上运行.
文件头还标识了文件类型,包括GUI、CUI或者DLL,并包含一个时间标记来指出文件的生成时间.对于只包含IL代码的模块,PE32+头的大多数信息会被忽视.如果是包含本机CPU代码的模块,这个头包含与CPU代码有关的信息.
CLR头:包含使这个模块成为托管模块的信息(可由CLR和一些实用程序进行解释),头中包含要求的CLR版本,一些标志(flag),托管模块入口方法(Main方法)的MethodDef元数据token以及模块的元数据、资源、强名称、一些标志项及其他一些不太重要的数据项的位置/大小
元数据:每个托管模块都包含元数据表.主要有两种表:一种表描述源代码中定义的类型和成员,另一种描述源代码中引用的类型和成员.
IL(中间语言)代码:编译器编译源代码时生成的代码.在运行时,CLR将IL编译成本机CPU指令.
(2)、元数据详解
元数据简介:
元数据大致构成:包括com的"类型库"和"接口定义语言"(Interface Definition Language,IDL)文件,但CLR数据远比它们全面.
注:元数据总是嵌入和代码相同的EXE/DLL文件中,这使两者密不可分,由于编译器和源代码同时生成元数据和代码,把它们绑定到一起,并嵌入到最终生成的托管模块,所以元数据和IL代码永远不会失去同步.
元数据的用途:

1、元数据避免了对原生C/C++头和库文件的需求,因为在实现类型/成员的IL代码中,已经包含了有关引用类型/成员的全部信息,所以编译器直接从托管模块中读取元数据即可.
2、visual stdio的智能提示通过解析元数据的方式,来告诉我们一个类型有哪些属性、方法、字段、事件,来提高我们的开发效率.
3、CLR的代码验证过程中确保代码只执行类型安全的操作.
4、元数据允许将对象的字段序列化到内存中,在发送到另外一台机器,进行反序列化,重塑对象的状态.
5、元数据允许垃圾回收器跟踪对象生存期,垃圾回收器能判断任何对象的类型,并从元数据中知道那个对象的哪个字段引用了那个类型.
Microsoft的C#、Visual Basic,F#和IL汇编器总是生成包含托管代码(IL)和托管数据(可进行垃圾回收的数据类型)的模块。为了执行包含托管代码以及/或者托管数据的模块,最终用户必须在自己的电脑上安装CLR(目前作为.Net Framework的一部分提供)
C++编译器默认生成包含非托管(native)代码的EXE/DLL模块,并在运行时操纵非托管数据(native 内存),这些模块不需要CLR即可执行,通过命令行开关,C++编译器就更能生成包含托管代码的模块,当然用户必须安装CLR才能执行这种代码,在前面提到的所有的Microsoft编译器中,Misrosoft C++编译器是独一无二的,只有它才允许开发人员同时写托管代码和非托管代码,并生成到同一个模块中,它也是惟一一个允许开发人员在源代码中定义托管非托管数据类型的Microsoft编译器.它的灵活性是其他编译器无法比拟的,因为它允许开发人员在托管代码中使用原生C/C++代码,时机成熟之后在使用托管类型.
一、源代码-面向CLR的编译器-托管模块-(元数据&IL代码)的更多相关文章
- 四、CLR执行程序集中代码和IL代码简介
三.加载公共语言运行时中介绍了在安装了.Net Framework中加载公共语言运行时,公共语言运行时加载程序集的过程.以及通过vs stdio设置源码编译的目标平台的过程. 本问主要介绍公共语言加载 ...
- 【CLR via C#】CSC将源代码编译成托管模块
下图展示了编译源代码文件的过程.如图所示,可用支持 CLR 的任何一种语言创建源代码文件.然后,用一个对应的编译器检查语法和分析源代码.无论选用哪一个编译器,结果都是一个托管模块(managedmod ...
- [CLR via C#]1.2 将托管模块合并成程序集
原文:[CLR via C#]1.2 将托管模块合并成程序集 1.CLR是不和托管模块一起工作的,CLR是和程序集一起工作的. 2. 程序集是一个或多个托管模块/资源文件的逻辑性分组. 3. 程序 ...
- 【C#进阶系列】02 PE文件,程序集,托管模块,元数据——还是那个Hello world
好了,还是这张图,还是一样的Hello world. 因为本章其实很多都是讲一些命令行编译啊什么鬼的配置类的东西,要用的时候直接百度或者回头查书就可以了, 所以了解一下也就行了,也没有记录下来,接下来 ...
- CLR Via第一 章 知识点整理(3)CLR执行程序集的IL代码
在了解CLR运行之前让我们先简单了解一下IL 除了编译器编译的IL代码,IL也是一种汇编语言,也就是说我们可以直接编写IL代码,当然也有对应的IL编译器,值得一提的是对于面向CLR的其他语言,CLR只 ...
- .Net Framework 之 托管模块与程序集的关系
一.基本概念: --托管模块:一个标准的32的可移植执行体(PE32)文件或一个标准的64位可移植执行体(PE32+)文件.由用支持CLR的任何一种语言创建的源代码文件,再经过相应的编译器检查语法和分 ...
- 【C#基础概念】程序集与托管模块的概念
本文是为了学习程序集而整理的网上资料,主要包括两个部分,概念和使用,前部分讲怎样理解程序集,后部分讲述怎样使用的细节. 程序集与托管模块的概念 "程序集与托管代码块"(摘自Hima ...
- 程序集的内部结构(托管模块、元素局、IL代码的分布情况)
程序集的内部结构 在看程序集的结构之前,我们先来看托管模块的结构. 托管模块由四部分组成:PE32头.CLR头.元数据(Metadata).IL代码.其中PE32头是用来决定托管模块运行的系统环境(3 ...
- Cocos2d-x源代码解析(1)——地图模块(3)
接上一章<Cocos2d-x源代码解析(1)--地图模块(2)> 通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo.CCTMXTilesetInf ...
随机推荐
- CentOS7 64位 安装MySQL5.7
安装环境:CentOS7 64位 MINI版,安装MySQL5.7 1.配置YUM源 在MySQL官网中下载YUM源rpm安装包:http://dev.mysql.com/downloads/repo ...
- 用vue2.x注册一个全局的弹窗alert组件
一.在实际的开发当中,弹窗是少不了的,默认系统的弹窗样式太丑,难以满足项目的实际需求,所以需要自己定义弹窗组件,把弹窗组价定义为全局的,这样减少每次使用的时候引入麻烦,节省开发时间.本文将分享如何定义 ...
- vue.js权威指南 PDF
链接:https://pan.baidu.com/s/1c2ItN6S 密码:ya8r
- Android破解学习之路(一)——简单的登录破解
最近突然心血如潮开始学了Android破解,初入门,便是将经验记录下来. 准备工作: 1.一个登录简单APP 在我们破解之前,我们需要做一个简单的登录APP,输入相应的账号与密码便是弹出登录成功的对话 ...
- hdu 1151 Air Raid DAG最小边覆盖 最大二分匹配
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1151 题目大意: 城镇之间互相有边,但都是单向的,并且不会构成环,现在派伞兵降落去遍历城镇,问最少最少 ...
- 五十个小技巧提高PHP执行效率(二)
更详细具体的总结如下: 1.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的 ...
- ConcurrentHashMap原理分析(1.7与1.8)
前言 以前写过介绍HashMap的文章,文中提到过HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新 ...
- 76、django之内置Admin
本篇导航: 配置路由 定制Admin Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django ...
- C#使用ManagementObjectSearcher来获取系统信息时会有out of memory的异常
在开发环境下,时不时出现out of memory的异常,最后是在服务界面重新启动 Windows Management Instrumentation后就好了.
- 栈和队列的java简单实现
今天看了一本书<啊哈 算法>,书的内容不多,一共两章,第一章是常见的排序算法包括桶排序.冒泡排序和快速排序,这些事基础的排序算法网上有很多资料说明,这里主要说第二章栈,对列,链表,书上使用 ...