关于Mono .Net IL2CPP的理解

一:什么是.Net?

.Net是微软的一种技术平台/一种规范,而不是一种语言,可以理解为接口

.NET平台支持多种语言开发:C#、F#、Visual Basic等

目前.Net有三种主流实现

——.Net Framework:主要是基于Windows上开发

——.Net Core:支持跨平台开发

——Mono:支持跨平台开发

跨平台的并不是C#,而是C#编译器编译后的中间语言CIL

二:.Net代码的编译过程

首先我们写的代码通过特定语言的编译器编译成CIL(Common Intermediate Language:中间语言,也可以称为IL或MSIL),它是一种托管代码类似于Java的虚拟机,它会存储在.DLL或.EXE的程序集中,CIL是一种伪代码不能被计算机直接识别。它与平台操作系统无关与CPU无关是一种中间语言,这也为跨平台奠定了基础。之后在程序运行时再通过CLR(Common Language Runtime:公共语言运行时)内部的JIT编译器将CIL编译成计算机可以识别的CPU指令(机器码:01010101),IL语言是在CLR中运行的,而CLR并不知道IL是由哪种语言编译而来

这是一个二次编译的过程

我们知道程序运行时候需要占用计算机的内存,C++的程序员是需要自己手动操作管理内存的,需要自己分配和释放内存。但是.NET程序员是不需要进行这个操作的,这是因为CLR帮我们自动做了分配内存和释放内存的操作。

托管代码与非托管代码:

例如C#,Java等,托管代码包含中间语言,需要经过虚拟机/CLR转换为CPU指令,代码执行效率低,但是它不依赖于操作系统和CPU,在各个操作系统上都能执行,它是运行在虚拟机/CLR上的。

例如C++等,非托管代码是直接对接CPU指令,代码执行效率高,但是不同的操作系统需要单独编写代码,重复低效,它是运行在机器上的。C++能跨平台可以理解为每个平台都实现了一套解析c++的运行库。

三:什么是Mono?

因为.Net Framework本身只能在Windows平台上运行,对于跨平台的需求Mono就产生了

Mono是基于CLI和C#的ECMA标准提供的.Net的另一种实现,与.Net不同的是它将CLR在所有支持的平台上重新实现了一遍(安卓、Switch,PS4)并且还将.Net Framework提供的基础类库也重新实现了一遍

四:Mono的组成

——C#编译器:C#编译器称为mcs,可以完成C#的编译工作,作用就是将C#源码编译成中间语言CIL,在非Windows平台上需要Mono运行时来运行,而在非Windows平台上既可以用.Net运行时,也可以使用Mono运行时

——Mono运行时(Mono VM): 实现了ECMA公共语言架构,提供了一个即时编译器(JIT)、预编译器(AOT)、类库加载器、垃圾回收器、线程系统和互操作性功能

——基础类库(.Net类库):提供一组全面的类,这些类兼容.Net框架并保持一致,是构建程序的结实基础

——Mono类库:提供了很多超越基础类库的类,提供了额外的功能,例如一些处理Gtk+,Zip文件,LDAP,OpenGL、Cairo、POSIX等等

五:什么是Mono运行时?

C#编译器mcs的作用是将C#源码编译成中间语言CIL,Mono运行时的作用是将CIL转换成机器语言

Mono运行时提供了三种转译方式

——即时编译(JIT):在运行过程中,将CIL编译成机器码。它是在程序运行时才编译代码,解释一条语句执行一条语句,同时也会将编译过的代码进行缓存,而不是每一次都进行编译

——提前编译(AOT):在运行前,将CIL编译成机器码并储存起来,但还是有一部分编译需要用到JIT

——完全静态编译(Full AOT):在运行前,将所有CIL编译成机器码,例如在IOS平台上是禁止JIT的,所以Mono只能以Full AOT模式运行

六:IL2CPP

由于Mono的一些不足而引发出了一种新的解决方案:IL2CPP,在得到中间语言IL后,使用IL2CPP将他们重新变回C++代码,然后再由各个平台的C++编译器直接编译成能执行的机器码

IL2CPP很好理解她的含义:将IL代码转换成CPP文件

现在的大趋势都是把语言加上动态特性,哪怕是C++这样的静态语言,也出现了适合IL的C++编译 器,那为什么Unity要把IL再转回静态的CPP呢?原因如下:

——Mono VM在各个平台移植,维护非常耗时,有时甚至不可能完成

Mono的跨平台是通过Mono VM实现的,有几个平台,就要实现几个VM,像Unity这样支持多平台的引擎,Mono官方的VM肯定是不能满足需求的。所以针对不同的新平台,Unity的项目组就要把VM给移植一遍,同时解决VM里面发现的bug,这非常耗时耗力。而且有些平台无法进行移植

2.Mono版本授权受限

因为Mono的授权受限,Unity无法升级Mono版本导致一些新的C#特性无法使用,如果换作是IL2CPP,IL2CPP VM这套完全自己开发的组件,就解决了这个问题

3.提高运行效率

根据官方的实验数据,换成IL2CPP以后,程序的运行效率有了1.5-2.0倍的提升

七:Mono和IL2CPP总结

——IL2CPP只支持AOT方式,Mono支持AOT,JIT所有方式

——平台支持:Android平台支持Mono和IL2CPP的所有编译方式,而IOS只支持Mono的Full AOT模式和IL2CPP

猜你喜欢

转载自blog.csdn.net/m0_74022070/article/details/131721987