浅谈Unity与.Net、Mono、IL2CPP

本文详细介绍了.NET平台及其主要实现.NET Framework、.Net Core和Mono的区别,重点阐述了Mono在CIL编译和跨平台运行中的角色,以及IL2CPP的作用。涵盖 Mono的组成,包括C#编译器、运行时、基础库和类库。
摘要由CSDN通过智能技术生成

一:什么是.Net?

.Net是微软的一种技术平台/一种规范,而不是一种语言,可以理解为接口
.NET平台支持多种语言开发:C#、F#、Visual Basic等
目前.Net有三种主流实现
——.Net Framework:主要是基于Windows上开发
——.Net Core:支持跨平台开发
——Mono:支持跨平台开发


二:.Net代码在Mono下的编译过程

首先我们写的代码通过特定语言的编译器编译成CIL(Common Intermediate Language:中间语言,字节码,也可以称为IL或CIL),它是一种托管代码类似于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提供的基础类库也重新实现了一遍
Unity能够跨平台的并不是因为C#这种语言能够跨平台,而是通过Mono实现了跨平台,Mono将C#代码又实现了一遍并在运行时运行在Mono虚拟机上


四: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

在得到中间语言IL后,使用IL2CPP将IL转换成C++代码,然后再由各个平台的C++编译器直接编译成机器码,最终生成的可执行文件包含的是经过编译的本地机器码,可以直接在目标平台上运行
IL2CPP很好理解:将IL代码转换成C++代码
那为什么Unity要把IL再转回静态的CPP呢?原因如下:
——Mono VM在各个平台移植,维护非常耗时,有时甚至不可能完成
Mono的跨平台是通过Mono VM实现的,有几个平台,就要实现几个VM,像Unity这样支持多平台的引擎,Mono官方的VM肯定是不能满足需求的。所以针对不同的新平台,Unity的项目组就要把VM给移植一遍,同时解决VM里面发现的bug,这非常耗时耗力。而且有些平台无法进行移植。
——提高运行效率
因为是直接将IL代码转换成了C++代码再转换成本地机器码,而不是动态编译,所以它的运行效率比Mono的运行效率更高


七:Mono和IL2CPP总结

——IL2CPP只支持AOT方式,Mono支持AOT,JIT所有方式
——平台支持:Android平台支持Mono和IL2CPP的所有编译方式,而IOS禁止为动态分配内存赋予执行权限,只支持Mono的Full AOT模式和IL2CPP 
——IL2CPP也有一些限制,因为C++是静态语言,所以只能使用AOT编译,从而不支持一些动态代码生成和反射的高级功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello Bug.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值