浅谈C#编译过程和原理

最近在研究学习C#的时候,研究了一下C#的运行原理和编译过程,多次查找各种文章和书籍总结后得出的结论,新手入门,只为总结记录,有问题的地方还望有人能看见指正

C#的特点

首先先说一下C#的一些特点:
第一,C#是一种高级程式语言,所谓高级程式语言,和低级程式语言相比,更偏向于人的理解,所以需要进行编译转化为低级程式语言,才能够被计算机所能理解,因为计算机只认cpu指令,而人对cpu指令理解起来有难度。
高级程式语言有:C,C++,Java,C#,python等
低级程式语言:机器语言,嵌入式,汇编语言等
第二,从类型的角度来划分的话,有强弱两种类型,强类型语言就是需要强制数据类型定义,不允许隐式转换的语言,而弱类型语言就是可以忽略数据类型,允许隐式转换的语言,所以,C#自然是属于强类型语言,所以C#是一种相对安全的语言。
强类型语言有:Java,C#,python等
弱类型语言有:C,C++,JavaScript等
第三,从确定类型的时间划分的话,有动静两种类型,动态语言就是在运行的时候才检查确定数据类型,而静态语言就是在编译的时候就检查确定数据类型,所以,C#属于静态语言。
动态语言有:python,PHP,JavaScript等
静态语言有:C,C++,C#等

C#的两次编译

C#编译的过程中会进行两次编译,第一次是使用的IDE,比如VScode自带的编译器进行编译,第二次就是JIT编译。关于第一次编译没有过多的深入研究,JIT编译会在后面进行详细研究。

编译过程

C#的编译过程是从源代码开始的,通过IDE自带的编译器对源代码进行编译和检查,会生成托管模块,托管模块是可以多个或一个合成程序集,也就是我们常用的.dll和.exe文件,而程序集是不能自己执行的,所以必须要通过搭载在一个平台上进行运行, 这里就会用到CLR,CLR是一种虚拟机,它的其中一种功能就是加载程序集,然后在CLR上,会进行JIT编译,将IL编译成CPU指令。
过程中有几个重要的东西会在下面详细解释。
1.托管模块
2.CLR
3.JIT编译

托管模块

首先,托管模块一般是由四部分组成的,分别是CLR头,IL头,元数据和IL,其中,CLR头和IL头都是描述文件,本文不做过多解释,这里将一下元数据和IL,因为这两个涉及到后面的JIT编译,而且很重要。
元数据中一共有三张表去记录和描述程序中使用到的文件的信息,分别是:
1.引用表:也就是在引用到的类型和成员
2.定义表:定义的类型和成员
3.清单表:程序集中使用到的文件的信息
IL:中间语言,它是将源代码转换为机器语言中间的一种伪机器语言,作用就是能够通过IL,实现程序跨平台和灵活性等优点。

CLR

公共语言运行时,又叫公共语言运行库,是和Java虚拟机一样的一种运行时环境,CLR的功能包括:内存管理,程序集加载,安全性,线程同步和异常处理,这些都可以由面向CLR的所有语言使用,并保证底层应用和操作系统必要的隔离。
因为C#本身和Java一样,并不支持跨平台,但是可以通过CLR实现跨平台,各个面向CLR的语言都可以通过进行第一次编译成IL,然后通过CLR加载,再进行JIT编译成CPU指令,从而实现跨平台。

JIT编译

上面讲过在程序集通过CLR加载后,会进行第二次编译,也就是JIT编译,JIT编译就是即时编译,下面记录一下JIT编译的具体过程。
首先在Main函数执行前,会现在内存中开辟一块空间,来存储获取到的Main函数中的所有数据类型,这些数据类型的方法都会有一个入口,每一个入口都对应一个地址,这里为了分辨我们叫它地址A(通过这个地址A能够找到引用的方法),而这些入口在编译的时候就会变成JITCompiler函数。
在进入到JITCompiler函数体中以后,会通过元数据中的三个表记录的信息匹配到使用到的类名和函数名,这里能够通过元数据记录的信息得到IL中的地址,通过编译地址对应的IL,得到Cpu指令,存储到地址B,最后将地址A替换为地址B。
通过JIT编译不仅能够优化热点代码,还能提高效率,在实现跨平台的时候,不需要每一次执行前都全部编译,可以直接使用地址B的指令。

粗略的画了一个JIT编译过程图,希望能够帮助理解,有错望指正。

在这里插入图片描述

跨平台

接下来,记录一下对跨平台的粗略理解。
首先,C#本身是一种不支持跨平台的语言,所以需要一个虚拟机才能实现跨平台,而在Windows系统下,这个虚拟机就是CLR,而在比如Unity3D或Linux或其他平台,想要实现跨平台就需要使用Mono,Mono同样也是一种虚拟机。
正因为Unity3D中内嵌了一个Mono,所以说Unity3D可以通过Mono实现跨平台,这也是为什么能够使用多种语言对Unity3D的脚本进行编写。
实现跨平台可以理解为不同的语言编译成IL在不同的平台上通过不同的虚拟机的运行来实现跨平台。

只为记录笔记,有错误希望大佬能够指正。

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、创建工程     如图所示,在集成开发环境的File菜单中选择New->Project打开新建工程对话框我们选择工程类型为Visual C# Projects,在模板中选择Windows  Application,在Name处输入工程名称:HelloWindows,在Location中输入保存的路径。 确定后,系统自动为你生成了程序框架。   现在我们来简单地熟悉一下这个开发环境中。     这就是我们的开发环境!   A区是我们的工具箱,包括对数据库、组件、窗体控件等的支持,我们都可以选择并加入到form中,假如你找不到Toolbox,请在菜单View中选择Toolbox以打开它。   B区是我们的设计工作区(包括对界面、代码的设计)。   C区相当于我们在VC6中的workspace:Solution Explorer可以看成是以前的FileView,ResourceView和ClassView大家一定是很熟悉了,看到Solution Explorer中的 Form1.cs了吗?这就是Form1对应的C#文件,双击它就可以对Form1进行界面设计,鼠标右键单击Form1.cs在弹出菜单中选择View Code便可以查看对应的代码。   D区是属性窗口:类似我们在VC6中资源编辑器里的属性窗口,但功能更强大,对于屏幕上的组件比如按钮、列表框你都可以在这里直接修改其属性:如文字、背景色等。     我们接下去的任务是制作关于对话框,并添加菜单用于打开此对话框。     二、添加新的Form:关于对话框   选择菜单Project->Add Windows Form,在弹出的对话框中选择类别为Local Project Items,选择模板为Windows Form,在Name中输入文件名:AboutDlg.cs,确认。新的Form出现在工作区,我们在D区的属性对话框中修改Text为“关于”,选择BackColor为淡蓝色,你也可以尝试其它属性的改变。   接下去,我们打开Toolbox,选择Win Forms中的Label,然后在窗体中画出,并在属性对话框中修改Text为"VC知识库欢迎您!   http://www.vckbase.com",我们在Win Forms中再加入一个Button,修改Text为“确认”。     至此,对话框的界面我们设计好了,但当用户按下确认按钮的时候,我们如何关闭对话框呢?我们双击“确认”按钮,这样系统会为按钮自动添加按钮的处理代码,在其中我们添加Close()函数用以关闭,如下所示:     protected void button1_Click (object sender,   System.EventArgs e)   {   Close(); ///这是我们增加的一句   }     关于对话框已经完成了,我们接下去要做的是为主视窗添加菜单,当选择菜单中的关于,我们就弹出“关于对话框”,让我们继续吧...     三、为主视窗添加菜单     在SolutionView中双击Form1.cs打开Form1,在Toolbox->Win Forms中选择MainMenu,并在Form1中画出,在“TypeHere”字样处我们可以输入菜单条。     双击关于字样,系统会为我们添加该菜单条的处理代码,我们可以在其中添加打开"关于对话框"的代码:     protected void button1_Click (object sender,   System.EventArgs e)   {   AboutDlg dlg = new AboutDlg();///分配AboutDlg对象   dlg.ShowDialog();///显示对话框   }     好了,我们的程序写好了,让我们按F5看看效果吧!     后记:C#的功能远远不止与此,本文的目的是让用过VC6的朋友对C#中   WINDOWS应用程序的开发尽快上手,只当抛砖引玉。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值