在Unity3D中利用了Mono運行時來實現其腳本模塊的基礎。
先給出一個Mono的定義:
Mono是一個由Xamarin公司(先前是Novell,最早爲Ximian)所主持的自由開放源代碼項目。 該項目的目標是創建一系列匹配ECMA標準(Ecma-334和Ecma-335)的.NET工具,包括C#編譯器和通用語言架構。與微軟的.NET Framework(共通語言運行平臺)不同,Mono項目不僅可以運行於Windows系統上,還可以運行於Linux,FreeBSD,Unix,OS X和Solaris,甚至一些遊戲平臺,例如:Playstation 3,Wii或XBox 360。
那麼這裏很明顯可以看出:Mono具有跨平臺的能力。
Mono跨平臺的能力又是怎麼實現的呢?來看看Mono的組件:
1、C#編譯器:從Mono2.11版本開始,採用的編譯器叫mcs,它的作用是將C#編譯爲CIL(Common Language Infrastructure,通用中間語言,也叫MSIL微軟中間語言,這個語言能運行在所有支持CIL的環境中)
2、Mono運行時:運行時想要的是定義一個與具體語言無關的,跨架構系統的運行環境。其中有:即時編譯器(Just-in-time,JIT)、提前編譯器(Ahead-of-time compiler,AOT)、類加載器、垃圾回收器和線程系統等。C#代碼經mcs編譯成CIL後的byte code後就是在Mono運行時中經JIT或AOT轉譯爲原生碼(Native Code),這個原生碼可以在當前機器運行,這就是Mono跨平臺的原因。
3、基礎類庫:Mono平臺提供了很多基礎類,這些類庫與.NET框架兼容。
4、Mono類庫:Mono自帶的類庫。
總之,在我們使用Unity3D開發遊戲的過程中,C#代碼編譯的過程爲:
第一步:C#代碼到CIL的編譯(在mcs上發生)。
第二步:CIL到CIL位元碼的編譯(在mcs上發生)。
第三步:CIL位元碼到本地指令的編譯(在Mono運行時上發生,有3種轉譯方式,3種轉譯方式如下)
a. 即時編譯(Just-in-time,JIT):在程序運行的時候把CIL的位元碼轉譯爲目標平臺的原生碼。
b. 提前編譯(Ahead-of-time,AOT):在程序運行前就把CIL的位元碼轉譯爲目標平臺的原生碼並且存儲,但是並不是全部的CIL的位元碼都會提前轉譯並存儲,仍然會有一小部分的CIL位元碼會在程序運行的過程中轉譯。簡單來說就是AOT和JIT都有。
c. 完全靜態編譯(Full-ahead-of-time,Full-AOT):這種模式是完全的AOT,不允許在程序運行的過程中使用JIT編譯。程序在運行之前所有的代碼必須都已經被編譯成了目標平臺的原生碼。在ios平臺的Unity3D開發必須用到這種模式。