1. 程式人生 > >Unity Android IL2CPP 編譯報錯的一種可能原因

Unity Android IL2CPP 編譯報錯的一種可能原因

Unity 版本 5.6.6f2

在使用 Android 的 IL2CPP 時,發生編譯報錯,報錯內容如下所示:

stdout:
IL2CPP error (no further information about what managed code was being converted is available)
Additional information: Build a development build for more information. δ�������������õ�������ʵ����
il2cpp.exe didn't catch exception: System.NullReferenceException: δ�������������õ�������ʵ����
   �� Unity.IL2CPP.Extensions.GetBaseType(TypeReference typeReference)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.AddStaticUsageRecursiveIfNeeded(TypeReference genericType)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.Process(Instruction instruction, MethodDefinition method)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.ProcessType(TypeDefinition type)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.Collect(AssemblyDefinition assembly)
   �� Unity.IL2CPP.AssemblyConverter.PreProcessStage(IInteropDataCollector interopDataCollector, ReadOnlyInflatedCollectionCollector& readOnlyGenericsCollectionCollector, TypeDefinition[]& allTypeDefinitions)
   �� Unity.IL2CPP.AssemblyConverter.Apply()
   �� Unity.IL2CPP.AssemblyConverter.ConvertAssemblies(NPath[] assemblies, NPath outputDir, NPath dataFolder, NPath symbolsFolder)
   �� Unity.IL2CPP.AssemblyConverter.ConvertAssemblies(IEnumerable`1 assemblyDirectories, IEnumerable`1 explicitAssemblies, NPath outputDir, NPath dataFolder, NPath symbolsFolder)
   �� il2cpp.Program.DoRun(String[] args)
   �� il2cpp.Program.Run(String[] args)
   �� il2cpp.Program.Main(String[] args)
stderr:

δ���������쳣:  System.NullReferenceException: δ�������������õ�������ʵ����
   �� Unity.IL2CPP.Extensions.GetBaseType(TypeReference typeReference)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.AddStaticUsageRecursiveIfNeeded(TypeReference genericType)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.Process(Instruction instruction, MethodDefinition method)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.ProcessType(TypeDefinition type)
   �� Unity.IL2CPP.GenericSharing.GenericSharingVisitor.Collect(AssemblyDefinition assembly)
   �� Unity.IL2CPP.AssemblyConverter.PreProcessStage(IInteropDataCollector interopDataCollector, ReadOnlyInflatedCollectionCollector& readOnlyGenericsCollectionCollector, TypeDefinition[]& allTypeDefinitions)
   �� Unity.IL2CPP.AssemblyConverter.Apply()
   �� Unity.IL2CPP.AssemblyConverter.ConvertAssemblies(NPath[] assemblies, NPath outputDir, NPath dataFolder, NPath symbolsFolder)
   �� Unity.IL2CPP.AssemblyConverter.ConvertAssemblies(IEnumerable`1 assemblyDirectories, IEnumerable`1 explicitAssemblies, NPath outputDir, NPath dataFolder, NPath symbolsFolder)
   �� il2cpp.Program.DoRun(String[] args)
   �� il2cpp.Program.Run(String[] args)
   �� il2cpp.Program.Main(String[] args)

UnityEngine.Debug:LogError(Object)
UnityEditorInternal.Runner:RunManagedProgram(String, String, String, CompilerOutputParserBase, Action`1) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/BuildUtils.cs:96)
UnityEditorInternal.IL2CPPBuilder:RunIl2CppWithArguments(List`1, Action`1, String) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:313)
UnityEditorInternal.IL2CPPBuilder:ConvertPlayerDlltoCpp(ICollection`1, String, String) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:304)
UnityEditorInternal.IL2CPPBuilder:Run() (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:151)
UnityEditorInternal.IL2CPPUtils:RunIl2Cpp(String, String, IIl2CppPlatformProvider, Action`1, RuntimeClassRegistry, Boolean) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:34)
UnityEditor.HostView:OnGUI()

從報錯資訊來看,是空引用異常,但是卻沒有指明錯誤的具體位置。另外,通過其他工程測試 IL2CPP 編譯是正常的,說明是當前工程的程式碼有問題。通過排除法來定位具體錯誤的位置,最終定位到程式碼裡有一個方法,如下:

static bool IsIosDeviceHighEnd()
{
    string generation = UnityEngine.iOS.Device.generation.ToString().ToLower();
    return list.Contains(generation);
}


雖然在 Android 下不會呼叫這個方法,但還是進行編譯了,而 UnityEngine.iOS.Device 是 iOS 系統的特殊功能介面,在 Android 的 IL2CPP 並沒有對應的 C++ 實現,所以就編譯錯誤了。

這裡可以通過加巨集來控制編譯,如下

#if UNITY_IOS
static bool IsIosDeviceHighEnd()
{
    string generation = UnityEngine.iOS.Device.generation.ToString().ToLower();
    return list.Contains(generation);
}
#endif

之後如果再遇到 IL2CPP 編譯錯誤,可以檢查下是否包含了 Android 平臺下沒有實現的方法介面之類的。