Unity Android IL2CPP 編譯報錯的一種可能原因
阿新 • • 發佈:2018-12-08
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 平臺下沒有實現的方法介面之類的。