Unity3d跨平臺原理

知乎的一個提問:unity3d跨平臺原理ios

 

一些資料:c#

IL

IL是.NET框架中中間語言(Intermediate Language)的縮寫。使用.NET框架提供的編譯器能夠直接將源程序編譯爲.exe或.dll文件,但此時編譯出來的程序代碼並非CPU能直接執行的機器代碼,而是一種中間語言IL(Intermediate Language)windows

優勢:

使用中間語言的優勢有兩點,一是能夠實現平臺無關性,既與特定CPU無關;二是 只要把.NET框架某種語言編譯成IL代碼,就實現.NET框架中語言之間的交互操做(這就是爲何unity3D裏面能夠c#和js混編)。(《C#程序設計及應用教程》(第2版), 馬駿 主編)
 
 
相關詞條:

Xamarin

Xamarin(現以被微軟收購)是mono項目的一個分支,但這裏面最大的區別Xamarin是商業項目.mono作爲跨平臺的框架已獲得愈來愈多的商業項目的確定,令外界擔憂的版權問題\可靠性\穩定性也獲得證明,使用mono最大的好處是可使用其它平臺衆多的項目解決方案,而沒必要被限制在windows平臺下貧乏而又昂貴的各類解決方案.bash

在Mac OS上,由於iOS的現有限制,面向iOS的C#代碼會經過AOT編譯技術直接編譯爲ARM彙編代碼。而在Android上,應用程序會轉換爲IL,啓動時再進行JIT編譯。框架

 

 

Mono在Full AOT模式下的限制

調試時遇到一個Mono運行時異常:函數

1
2
ExecutionEngineException: Attempting to JIT compile method  '...' 
while  running with --aot-only.

        最後發現緣由是使用了泛型接口,致使Mono須要JIT編譯,但在iOS平臺中,Mono是以Full AOT模式運行的,沒法使用JIT引擎,因而引起了這個異常。優化

        Mono的AOT和.NET的Ngen同樣,都是經過提早編譯來減小JIT的工做,但默認狀況下AOT並不編譯全部IL代碼,而是在優化和JIT之間取得一個平衡。因爲iOS平臺禁止JIT編譯,因而Mono在iOS上須要Full AOT編譯和運行。即預先對程序集中的全部IL代碼進行AOT編譯生成一個本地代碼映像,而後在運行時直接加載這個映像而再也不使用JIT引擎。目前因爲技術或實現上的緣由在使用Full AOT時有一些限制,具體能夠參考MonoTouch的文檔,這裏提幾條常見的:spa

  • 不支持泛型虛方法,由於對於泛型代碼,Mono經過靜態分析以肯定要實例化的類型並生成代碼,但靜態分析沒法肯定運行時實際調用的方法(C++也所以不支持虛模版函數)。設計

  • 不支持對泛型類的P/Invoke。3d

  • 目前不能使用反射中的Property.SetInfo給非空類型賦值。

  • 值類型做爲Dictionary的Key時會有問題,實際上實現了IEquatable<T>的類型都會有此問題,由於Dictionary的默認構造函數會使用EqualityComparer<TKey>.Default做爲比較器,而對於實現了IEquatable<T>的類型,EqualityComparer<TKey>.Default要經過反射來實例化一個實現了IEqualityComparer<TKey>的類(能夠參考EqualityComparer<T>的實現)。 解決方案是本身實現一個IEqualityComparer<TKey>,而後使用Dictionary<TKey, TValue>(IEqualityComparer<TKey>)構造器建立Dictionary實例。

  • 因爲不容許動態生成代碼,不容許使用System.Reflection.Emit,不容許動態建立類型。

  • 因爲不容許使用System.Reflection.Emit,沒法使用DLR及基於DLR的任何語言。

  • 不要混淆了Reflection.Emit和反射,全部反射的API都可用

 

JIT和AOT:

JIT:http://en.wikipedia.org/wiki/Just-in-time_compilation

AOT:http://en.wikipedia.org/wiki/AOT_compiler

http://www.mono-project.com/AOT

相關文章
相關標籤/搜索