咱们从基础概念开始,一步步走进真相:缓存
一个.Net程序由一个或者多个程序集组成,程序集能够是库,也能够是应用程序。.Net中,库项目导出的文件格式为.dll,应用程序导出后的文件格式为.exe。框架
相似Flash项目,也是由库项目和应用程序项目组成。在Flash中,库项目导出后的文件格式为.swc,应用程序导出后的文件格式为.swf。函数
好比:通常Unity项目里包含这四个C#库项目:测试
vs编译以后,而后咱们在项目目录的缓存目录Library\ScriptAssemblies下,能找到对应的四个dll文件:翻译
刚才咱们提到C#库项目导出以后生成的是一个DLL文件, 这个DLL文件里,存放的是CIL代码集。3d
它是微软在发布.Net框架的时候,一块儿发布的一个语言。CIL语言大概长这个样子:cdn
它本来的C#程序是这样:blog
在.Net平台下,全部的语言(C#,VB.NET等)都会被编译成CIL,而后运行在虚拟机上,由虚拟机把CIL转换成各个平台的原生码(CPU可直接执行的代码)。游戏
是否是又有点像Flash,Flash程序也是运行在虚拟机上的。ip
你们在Unity项目中都见过Mono这个词,MonoDeveloper,MonoBehavior等,那Mono究竟是个什么东西?
Mono是一个基于CLR的开源项目,容许引擎和用户的托管代码运行在每个目标平台上。而CLR全称为通用语言运行平台(Common Language Runtime),是微软的.Net虚拟机。它其中两个主要做用是:1,编译——运行前把C#编译为CIL;2,运行——在运行的时把CIL转换成各平台的原生码。
这些是Mono支持的平台:Android,Apple iOS(iOS,Apple macOS,Apple tvOS,Apple watchOS),BSD (OpenBSD, FreeBSD, NetBSD),Linux,Microsoft Windows,Nintendo Wii,Sony PlayStation 3,Sony PlayStation 4,Sun Solaris
刚才咱们已经知道了Unity跨平台是如何作到跨平台的:
一、把C#经过Mono compiler(其余语言用的是Unity单独开发的一个Unity compiler),编译成CIL语言;
二、各个平台下的Mono虚拟机,运行CIL语言,转换成原生码给CPU执行。
其实Unity后来出了另一个方案:IL2PP。
它会在项目转成CIL以后,再把CIL转成CCPP,而后在运行的时候,把CPP加载进来,由各个平台的IL2PP VM转换成原生码。
Mono模式下编译出来的安卓包体:
IL2CPP模式下编译出来的安卓包体:
一、运行速度快(CPP转原生码比CIL快);
二、减小Unity公司的维护成本:Mono VM官方是不支持那么多平台的,因此不少平台的Mono VM都须要Unity本身去制做和维护,而C++编译器是原本各个平台都现成的。
一、包体会变大;
三、不支持JIT。
这个部分将会告诉你们,IOS平台究竟有和特别之处,为何在它上面实现代码热更新那么麻烦。
(留个坑:AOT模式下,编译出来的内容有两部分:原生码和CIL,它们是如何存放的,找了好多资料,没查到,本地想测试,可是环境暂时搭不起来,这个后面和IL2CPP一块儿研究)
Windows和Android系统采用的是JIT模式,那IOS用的哪种呢?
咱们看到,JIT模式是边运行,边翻译,支持运行时加载新的代码进来。而IOS是禁止内存的可执行权限的,不容许在运行过程当中建立新的函数等,因此必需要提早编译好全部的代码,更不用说在运行时加载新的代码了。就是说,在IOS下,Mono采用的是Full AOT模式运行CIL。