IL2CPP深入詳解-總覽


導語

該系列將會分為以下幾個部分:
1. 總覽(本文)
2. c++代碼解析
3. 調試c++代碼
4. 方法調用(一般方法,虛方法等)
5. 泛型共享
6. 類型與方法的 P/invoke 封裝
7. 垃圾回收
8. 測試框架與使用

什么是IL2CPP

IL2CPP 是 Unity 自 4.6.1p5版本 提出的一種新的 scripting backend 方式,為Unity提供了更加高效、更加便攜的虛擬機,IL2CPP分為兩個獨立的部分:

  • AOT(靜態編譯)編譯器
  • 運行時庫

其中AOT編譯器將 IL(由.Net編譯器輸出的中間語言)轉換為C++源碼,而運行時庫則會提供諸如 垃圾回收、線程/文件獲取(獨立於平台,與平台無關)、內部調用直接修改托管數據結構的原生代碼 的服務與抽象。

AOT編譯器

所謂AOT編輯器即 il2cpp.exe
在 Windows 系統中你可以在 Editor\Data\il2cpp 目錄中找到它,
在 OSX 系統中你可以在 Contents/Frameworks/il2cpp/build,即Unity的安裝目錄中找到它。
il2cpp.exe 是由C#編寫的受托管的可執行程序,它接受我們在Unity中通過Mono編譯器生成的托管程序集,並生成指定平台下的C++代碼。

IL2CPP的工具鏈如下圖所示:

il2cpp-toolchain

運行時庫

IL2CPP技術的另一部分是運行時庫(libil2cpp),它的存在是為了支持IL2CPP虛擬機的運行,運行時庫幾乎完全由C++代碼編寫,並作為一個靜態庫與最終的可執行程序鏈接。(值得一提的是,IL2CPP技術十分得益於使用了libil2cpp這一更輕便的運行時庫)

你可以通過查看 libil2cpp 的頭文件了解其的代碼構成(Windows 系統下的目錄為Editor\Data\PlaybackEngines\webglsupport\BuildTools\Libraries\libil2cpp\include,OSX 系統下的目錄為 Contents/Frameworks/il2cpp/libil2cpp),例如你可以在 codegen/il2cpp-codegen.h 文件中看到 il2cpp.exe 生成C++代碼的接口以及 運行時庫 的接口。

運行時庫的另一關鍵功能是提供了垃圾回收,這一塊內容將在后續的文章里再詳細探討。

AOT編譯器是如何運行的

讓我們來看一個例子(該例子運行在 Windows 系統下 Unity 5.0.1版本中)
開啟一個新的工程,將如下腳本添加至主相機上:

  1.  
    using UnityEngine;
  2.  
     
  3.  
    public class HelloWorld : MonoBehaviour
  4.  
    {
  5.  
    void Start ()
  6.  
    {
  7.  
    Debug.Log( "Hello, IL2CPP!")
  8.  
    }
  9.  
    }

此時我們發布一個WebGL平台下的程序,並使用 Process Explorer 工具查看Unity通過什么命令行對 il2cpp.exe 進行了調用:

  1.  
    "C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe"
  2.  
    "C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe"
  3.  
    --copy-level=None
  4.  
    -- enable-generic-sharing
  5.  
    -- enable-unity-event-support
  6.  
    --output-format=Compact
  7.  
    --extra-types.file= "C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt"
  8.  
    "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll"
  9.  
    "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll"
  10.  
    "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\il2cppOutput"

這個命令行看起來又復雜又嚇人,不用擔心,讓我們逐步來解析它,

"C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe" 

首先,Unity啟動 mono.exe

  1.  
    "C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe
  2.  
     

接着啟動 il2cpp.exe


剩下的命令行則是傳遞給 il2cpp.exe ,而非傳遞給 mono.exe的參數,首先這里傳遞了5個標識符給 il2cpp.exe:


–copy-level=None

告訴 il2cpp.exe 不要復制生成的C++代碼.

enable-generic-sharing 

IL2CPP將會共享泛型以此來減少最終包體的大小。

enable-unity-event-support 

支持通過反射獲取的Unity事件,保證代碼能夠正確生成。

–output-format=Compact

在生成的C++代碼中,為類與方法使用更少的字符數來命名,這樣會使得代碼更難以調試,因為IL代碼的命名將會發生改變(筆者注:應該類似於代碼混淆),但是卻能夠被編譯器更快編譯,因為編譯器所需要解析的字符數變少了。

–extra-types.file=”C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt”

使用默認的 額外類型文件 ,這個文件會被加入到你的Unity工程里,並告知 il2cpp.exe 哪些泛型類型或者數組類型沒有在IL代碼中出現,卻會在運行時被創建。


值得注意的是這些命令行也許會在后續的Unity版本中發生變化。最后,讓我們看看剩下的三條命令行。


  1.  
    “C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll”
  2.  
    “C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll”

il2cpp.exe 接受所有應該被轉換的 IL 程序集,在這里例子中它應該包含我的 MonoBehaviour腳本、 Assembly-CSharp.dll 以及 GUI assembly 和 UnityEngine.UI.dll ,很顯然,上面的命令行里似乎少了些什么, 我的腳本引用了 UnityEngine.dll 和 mscorlib.dll,但是它們卻沒有被包含在上述的命令行中,那么它們在哪兒呢?事實上,il2cpp.exe 在內部對這些程序集進行了處理,因此在上述的命令行中它們不是必須的,Unity只顯式地需要 根程序集(不被任何程序集引用的程序集)在命令行中被提及。

“C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\il2cppOutput”

最后的一個參數表示 il2cpp.exe 的輸出目錄,即 il2cpp.exe 生成代碼的輸出位置,如果你對此感興趣的話,可以看一看生成目錄下的C++文件,而這一塊內容我們也會在后續的文章中對其進行詳解。此外,如果你希望瀏覽生成目錄下的代碼的話,推薦在出包的時候選擇 Development Player 模式,這樣一來將會移除 –output-format=Compact 命令行,使得你的代碼更具可讀性。

PS:你可以通過改變 Player Settings 中的設置來觀察 Unity 傳遞給 il2cpp.exe 的命令行的差異,例如將
Enable Exceptions 設置為 Full,那么命令行中就會增加 –emit-null-checks–enable-stacktrace 、 –enable-array-bounds-check 三項.

IL2CPP沒有做的工作

Unity官方並沒有重寫C#的標准庫,因此當你發布一個Unity工程的時候,即使你選擇了 IL2CPP 的方式來生成你的代碼,所有在 mscorlib.dll、System.dll 等標准庫中的代碼都將使用Mono2X的方式來生成。



作者:StalkerME
鏈接:https://www.jianshu.com/p/7cfcb7b0cfe7
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

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



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