Unity3D學習(一):簡單梳理下Unity跨平台的機制原理


前言

首先需要了解的是,Unity3D的C#基礎腳本模塊是通過Mono來實現的。

什么是Mono?

  參考下百度百科:Mono是一個由Novell公司(由Xamarin發起)主持的項目,並由Miguel de lcaza領導的,一個致力於開創.NET在Linux上使用的開源工程。它包含了一個C#語言的編譯器,一個CLR的Runtime,和一組類庫,並實現了 ADO NET和ASP NET。

  它基於CIL和C#的ECMA標准,提供了了微軟.Net FrameWork的另一種實現。

 Mono主要有以下部分組成:

  C#編譯器——mcs。(最新的Mono版本已經可以支持C#5.0,但Unity3D的Mono版本仍然停留在2.0+階段(支持c#3.0),所以C#的一些新功能無法在unity中使用)

  運行時:即時編譯器JIT(后文會介紹)。以及GC,類庫加載器等等。

  基礎類庫(BCL)。

  Mono類庫。提供了超出微軟.NET的一些類,提供了許多額外功能,主要是用於構建其他操作系統上的應用。

下面進入正題:

Mono和Unity

Unity引擎本身是由C++寫出的,只不過Mono被嵌入到了Unity當中,為unity提供了一個完整的虛擬機運行環境。這樣Mono的嵌入接口會將Mono Runtime暴露給Unity底層的C++代碼。通過這些接口,開發者就可以控制Mono Runtime,以及依托於Mono Runtime的托管代碼。

Unity為何能夠跨平台?

一句話概括,主要原因在於Unity通過Mono使用了一種叫CIL(Common Intermediate Language,也叫MSIL)通用中間語言的基於堆棧的代碼指令集,它屬於CLR的一個子集。

Unity3D的開發過程中,代碼的編譯主要分為兩個過程:

1)首先將對應的腳本代碼編譯成CIL(之后CIL還會被編譯成一種位元碼,生成一個CLI集合)。

2)然后Mono在運行時將CLI集合中的位元碼編譯為本地運行的原生指令。(這里會使用到上文中的JIT、AOT編譯模式)

注:也就是說在Mono中運行的其實是CIL,而在本地運行的是被編譯后生成的原生指令。

這里再提一下什么是JIT和AOT

JIT:即時編譯,或者又稱為動態編譯,是在程序執行時才編譯代碼,即將一條中間托管語句(CLI)翻譯成一條機器語句,然后執行這條語句。但它同時也會將編譯過的代碼進行緩存,而不是每一次都進行編譯。所以說它是靜態編譯和解釋器的結合體。

AOT:靜態編譯,同樣使用了JIT來進行編譯,只不過它在程序運行之前就編譯好了。但還是有一部分代碼會即時編譯。

AOT的過程簡要:

1)收集需要編譯的代碼。

2)使用JIT編譯代碼。

3)發射編譯過的代碼和一些元數據

4)調用本地匯編器或連接器處理后生成可執行文件。

注:IOS平台禁止使用JIT編譯器,所以Mono提供了一種FULL AOT模式,這里不贅述。

總結

Unity的跨平台,就是通過Mono將C#腳本代碼編譯成CLI,然后Mono運行時利用JIT或者AOT將CLI編譯成目標平台的原生代碼實現的。

參考資料

  1.百度百科

  https://baike.baidu.com/item/CIL/3583850?fr=aladdin

  https://baike.baidu.com/item/JIT%E7%BC%96%E8%AF%91%E5%99%A8/3793585

  2.電子工業出版社:《Unity3D腳本編程》  作者:陳嘉棟


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM