Mono
跨平台
IL
Intermediate Language,中間語言,面向對象的彙編語言
工作流
通過C#編譯器mcs,将C#編譯為IL(中間語言,byte code)
通過Mono運作時中的編譯器将IL編譯成對應平台的原生碼
IL三種轉譯方式
即時編譯(Just in time,JIT):程式運作過程中,将CIL的byte code轉譯為目标平台的原生碼。
提前編譯(Ahead of time,AOT):程式運作之前,将.exe或.dll檔案中的CIL的byte code部分轉譯為目标平台的原生碼并且存儲,程式運作中仍有部分CIL的byte code需要JIT編譯。
完全靜态編譯(Full ahead of time,Full-AOT):程式運作前,将所有源碼編譯成目标平台的原生碼。
Unity跨平台的原理
Mono運作時編譯器支援将IL代碼轉為對應平台原生碼
IL可以在任何支援CLI,通用語言環境結構)中運作,IL的運作是依托于Mono運作時。
IOS不支援jit編譯原因
機器碼被禁止映射到記憶體,即封存了記憶體的可執行權限,變相的封鎖了jit編譯方式
托管代碼
c#代碼生成的IL編碼,由虛拟機的JIT編譯執行,其中對象無須手動釋放,由GC管理
非托管代碼
C++/C#中以不安全類型寫的代碼,虛拟機無法跟蹤
托管代碼剝離
托管代碼剝離過程将分析項目中的程式集,以查找和删除未實際使用的代碼。分析過程使用一組規則來确定要保留的代碼和要丢棄的代碼。這些規則将在建構大小(包含太多代碼)與風險(删除太多代碼)之間進行權衡。Managed Stripping Level 設定可用于控制删除代碼的激程序度。
Mono建構
- 建構應用非常快
- 由于Mono的JIT(Just In Time compilation ) 機制, 是以支援更多托管類庫
- 支援運作時代碼執行
- 必須将代碼釋出成托管程式集(.dll 檔案 , 由mono或者.net 生成 )
- Mono VM在各個平台移植異常麻煩,有幾個平台就得移植幾個VM(WebGL和UWP這兩個平台隻支援 IL2CPP)
- Mono版本授權受限,C#很多新特性無法使用
- iOS仍然支援Mono , 但是不再允許Mono(32位)應用送出到Apple Store
IL2CPP
- 相比Mono, 代碼生成有很大的提高
- 可以調試生成的C ++代碼
- 可以啟用引擎代碼剝離(Engine code stripping)來減少代碼的大小
- 程式的運作效率比Mono高,運作速度快
- 多平台移植非常友善
- 相比Mono建構應用慢
- 隻支援AOT(Ahead of Time)編譯
IL2CPP概括:
- Mono将c#翻譯成IL
- IL2CPP得到IL轉變為C++代碼
- 再由各個平台C++編譯器編譯成可執行機器碼