一、源代码-面向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 ...
随机推荐
- Ipython自动导入Numpy,pandas等模块
一.引言 最近在学习numpy,书上要求安装一个Ipythpn,可以自动导入Numpy,pandas等数据分析的模块,可是当我安装后,并不能自动导入numpy模块,还需要自己import.我就去查了一 ...
- php中session 入库的实现
ini_set("session.save_handler","user");//session.gc_probability = 1 分子ini_set(&q ...
- django模板语法之include
假如我们有以下模板index.html,代码为: <!DOCTYPE html> <html lang="en"> <head> <met ...
- WPF依赖对象(DependencyObject) 实现源码,理解WPF原理必读
/// DependencyObject encompasses all property engine services. It's primary function /// is providin ...
- day4、Linux基础题目
第一题 我想在/data/da 目录下面创建 一个 da.txt 文件 [root@ll ~]# cd /data/oldboyedu -bash: cd: /data/oldboyedu: No s ...
- ettercap的中间人欺骗
环境准备:kali系统 因为kali系统自带ettercap,比较方便, 不需要安装 ifcofing命令查看当前网关 ,当前的IP是: 172.16.42.1 查找局域网所有主机 通过netdisc ...
- centos编译安装php5.6.20+nginx1.8.1+mysql5.6.17
LNMP 代表的就是:Linux系统下Nginx+MySQL+PHP这样的站点服务器架构. 本次实践需求: 实践centos6.5编译安装 LNMP生产环境 架构 web生产环境 使用 xcache ...
- iOS多线程与网络开发之发送接收server信息
郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. (1).使用同步方法发送get请求(不经常使用) 2 /** 发送get消息 */ 3 - (void) testGet { 4 NSString *r ...
- iOS_20_微博OAuth授权_取得用户授权的accessToken
终于效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill ...
- Mybatis实现 --文件夹
本文是关于MyBatis的实现机制的探索,文章大量參考了网络上已有的相关文章并结合最新版本号的Mybatis做的整理 文件夹例如以下: Mybatis实现[1] ---Mybatis Basic[Ja ...