- Home /
IL2CPP support for Linq
Hello,
I am building an Android app in Unity 2018.3.6 with IL2CPP, ARM64 and .NET 4.x.
There is some code from a previous programmer which reads:
IEnumerable<Node> listOfNodesThatMatch = parentXmlNodeWithChildren.Select("criteraToMatch");
When building using Mono and ARM32 this code executes fine, but on IL2CPP it throws the error:
IL2CPP encountered a managed type which it cannot convert ahead-of-time. The type uses generic or array types which are nested beyond the maximum depth which can be converted.
Based on this page of the documentation, it seems IL2CPP uses Ahead-of-time compile. This forum post also warns against using LINQ with AOT and recommends using UniLinq to avoid these errors, but based on the github page for UniLinq, its now obsolete because IL2CPP should be supporting LINQ. I'm obviously not seeing it as fixed on my end so I'm reading this all as a bit of circular logic.
Is LINQ supported for IL2CPP? If not, how can I change the code presented to maintain the same functionality? If it is supported, what part of IL2CPP could be causing problems in the code I mentioned?
Thank you,
-Christopher Poole
Edit: This was not a problem with Linq but rather a problem with nested arrays. The XML implementation gave each node an array of child nodes who then had their own arrays of child nodes and so on and so on until it hit the upper limit of nested arrays IL2CPP can handle.
It looks like the problem when serializing circular data. Not sure why this can't get compiled but you don't present much of what's going on.
Assu$$anonymous$$g each Node holds references of other Nodes (neighbours), you could replace these refs with an index or coordinates pointing to the actual node.
Answer by JoshPeterson · Sep 17, 2019 at 12:07 PM
IL2CPP does support LINQ, so it can be used in general cases.
In this specific case, the code is bumping up against a limit of how many nested generic types IL2CPP is willing to process. For example, it is possible to get recursive generic type definitions like this:
GenericOne<GenericTwo<GenericOne<GenericTwo<int>>>>
IL2CPP will only convert code for generics nested 7 levels deep. It has to stop at some point, or it could go on forever expanded these generic types.
This error message means that code in the project actually tried to call a generic type nested more than 7 levels deep. I guess that is possible with LINQ, but it is probably a bad idea in any case, so I would expect code like that to be rather difficult to humans to understand.
I doubt that the Select call mentioned above it causing this issue, as it looks pretty benign. Is there some other complex LINQ expression or generic code near this that might be causing the problem?
With your and PizzaPie's answers in $$anonymous$$d I checked the code used to define what an xml node is (not part of any library just hand made). It seems like each node has an array of references to its child nodes. In your example you talk about nested generic types, but the error I got does say "generic or array types". Does that mean the nested arrays representing nested children are causing the problem? $$anonymous$$y xml is definitely more than 7 layers deep.
Yes, nested arrays have the same limitation. so as generic type like this could be a problem as well:
SomeGenericType<int[][][][][][][][]>
Well that's definitely the problem then! I imagine XDocument won't have this problem since its a more standardized library?
Your answer
Follow this Question
Related Questions
Unity Android IL2CPP Build Error 1 Answer
How to post process Unity-built dll before il2cpp kicks in? 1 Answer
No Line numbers in stack trace for debug android build using IL2CPP 1 Answer
How to add compiler or linker flags for il2cpp invocation. 3 Answers
Can't build for Android with IL2CPP 1 Answer