Unity中的mono和IL2CPP
mono
- mono 是JIT编译的,动态的一边将IL加到内存中,一边去编译解释(通过反射获取确定要使用类型),所以支持更多托管类库
- mono VM受平台限制,有几个发布平台就要有几个对应的mono VM
IL2CPP
可以看出这种方式通过IL2cpp.exe是直接将IL转译成C++文件(代码剪裁),然后通过C++编译器生成本机可执行的asm(字节码),由IL2CPP VM(用C#编写)进行编译解释和GC管理
- IL2CPP 由于C++语言的特性,只支持AOT
- 运行代码包体和效率要比mono高,构建时比mono慢
由于代码剪裁带来的某些泛型类型无法使用的问题,为此引入了Generic Sharing(泛型代码共享)的概念,CLR中也有同样的概念,CLR认为所有引用类型实参都一样,所以可以代码共享,例如,为List<String>方法编译的代码可以直接用于List<Stream>方法,这是因为所有引用类型实参/变量只是指向托管堆的一个8字节指针(这里假设64位系统),但是对于值类型,则必须每种类型都进行代码生成,因为值类型大小不定。以此这个问题得以解决。
同时
Unity提供了一个方式来告诉Unity引擎,哪些类型是不能够被剪裁掉的。具体做法就是在Unity工程的Assets目录中建立一个叫link.xml的XML文件,然后按照下面的格式指定你需要保留的类型:
<linker> <assembly fullname="UnityEngine" preserve="all"/> <assembly fullname="Assembly-CSharp"> <namespace fullname="MyGame.Utils" preserve="all"/> <type fullname="MyGame.SomeClass" preserve="all"/> </assembly> </linker>