# HybridCLR AOT 泛型問題 (補充元數據) ## HybridCLR 官方詳解 - [HybridCLR AOT 泛型](https://hybridclr.doc.code-philosophy.com/docs/basic/aotgeneric#aot%E6%B3%9B%E5%9E%8B%E9%97%AE%E9%A2%98) ## AOT 泛型問題 在 il2cpp AOT 基本上幾乎所有類型都在編譯期間靜態確定了,導致如果我 Hotfix 工程要調用 AOT 特定泛型類,必定會出錯,因為沒有經過編譯確認該類型,也沒分配過該類型的內存,以下將會以**兩大機制**進行概述。 ## 機制 1 - 泛型共享機制 支持: - 內置類型 (built-in types) <font color=#FF006F size=2>sharing type 為 self</font> - 整數類型:int, byte, short, long, uint, ushort, ulong - 浮點數類型:float, double - 布林類型:bool - 字符類型:char - 枚舉類型 <font color=#FF006F size=2>sharing type 為 underlying type (int) 或與它相同的枚舉</font> ```csharp (enum) // EnumA 共享 EnumB (int) enum EnumA { A1, A2 } enum EnumB { B1, B2 } // EnumC 共享 EnumD (short) enum EnumC : short { C1, C2 } enum EnumD : short { D1, D2 } ``` - 引用類型 (class) <font color=#FF006F size=2>sharing type 為 object</font> 不支持: - 自定義結構體的值類型 (struct) ### 流程情境 於 AOT 中,實例一次: ```csharp // AOT 工程 var l1 = new List<byte>(); var l2 = new List<short>(); var l3 = new List<int>(); var l4 = new List<float>(); // And more... ``` 於 Hotfix 中,啟用『<font color=#ed8a00>泛型共享機制</font>』,我將可以在 Hotfix 中使用以下類型: ```csharp // Hotfix 工程 List<byte>(); List<short>(); List<int>(); List<float>(); ``` ### il2cpp 中值類型 (struct) 不支持泛型共享 主要是因為內存對齊引發的問題,像是以下內存大小分配雖然一樣 <font color=#EE82EE size=2>(皆為 4 bytes)</font>,但是內存對齊不同。 ```csharp /// <summary> /// Size 4 bytes, alignment 2 bytes /// </summary> struct A { byte x; // 1 byte short y; // 2 bytes (alignment 2) } /// <summary> /// Size 4 bytes, alignment 4 bytes /// </summary> struct B { int x; // 4 bytes (alignment 4) } ``` 但是如果該值類型 (struct) 於 AOT 中定義,並且也在 AOT 實例過,則於 Hotfix 中依然可以直接使用,只是『無法啟用泛型共享機制 (<font color=#ff0000>X</font>)』。 ### 總結 如果該類型在 AOT 都已經確認了,並且於 AOT 中實例過一次,那麼就可以在 Hotfix 中,調用 AOT 泛型類與該 AOT 類型,則選擇『<font color=#ed8a00>泛型共享機制</font> <font color=#EE82EE size=2>(於 AOT 全類型實例一次)</font>』。 ## 機制 2 - 補 AOT 元數據 ### 流程情境 假設,我於 Hotfix 中定義以下引用類型: ```csharp // Hotfix 工程 struct MyAttrs { float x; float y; float z; } ``` 接下來,使用 AOT 泛型類,指定 Hotfix 中定義的 <font color=#e60060>List</font>\<<font color=#0090d9>MyAttrs</font>\> 引用類型,顯然『不可能提前 AOT 中泛型實例化 (<font color=#ff0000>X</font>)』。 ### 總結 如果該類型於 Hotfix 中定義,但是又使用 AOT 泛型類指定該 Hotfix 中定義的類型,這時候只能選擇『<font color=#ed8a00>補 AOT 元數據</font>』。 > <font color=#008aed size=2>效率:泛型共享機制 \> 補 AOT 元數據。</font> > > 如果 AOT 泛型補充了相應的泛型元數據,並且 il2cpp 泛型共享實例化也存在,為了最大化性能,HybridCLR 將優先嘗試 il2cpp 泛型共享。 - <font size=2>[引用自官方文檔](https://hybridclr.doc.code-philosophy.com/docs/basic/aotgeneric#%E5%9F%BA%E4%BA%8E%E8%A1%A5%E5%85%85%E5%85%83%E6%95%B0%E6%8D%AE%E7%9A%84%E6%B3%9B%E5%9E%8B%E5%87%BD%E6%95%B0%E5%AE%9E%E4%BE%8B%E5%8C%96%E6%8A%80%E6%9C%AFhybridclr%E7%9A%84%E4%B8%93%E5%88%A9%E6%8A%80%E6%9C%AF)</font>