Unity3d跨平台原理


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

 

一些資料:

IL

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

優點:

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

Xamarin

Xamarin(現以被微軟收購)是mono項目的一個分支,但這里面最大的區別Xamarin是商業項目.mono做為跨平台的框架已得到越來越多的商業項目的肯定,令外界擔心的版權問題\可靠性\穩定性也得到證實,使用mono最大的好處是可以使用其它平台眾多的項目解決方案,而不必被限制在windows平台下貧乏而又昂貴的各種解決方案.

在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的文檔,這里提幾條常見的:

  • 不支持泛型虛方法,因為對於泛型代碼,Mono通過靜態分析以確定要實例化的類型並生成代碼,但靜態分析無法確定運行時實際調用的方法(C++也因此不支持虛模版函數)。

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

  • 目前不能使用反射中的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

 

 


免責聲明!

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



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