Closed zakrzus closed 4 years ago
I've done some research and got message:
ExecutionEngineException: Attempting to call method 'InvokableCallback`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]::.ctor' for which no ahead of time (AOT) code was generated.
The AOT compiler does not realize that it should generate code probably for constructor in class SerializeCallback.cs
@zakrzus Did you find any simple solutions to this?
I found this documentation: https://docs.unity3d.com/Manual/ScriptingRestrictions.html#AOT and https://github.com/aws/aws-sdk-net/issues/477
Apparently, you need to explicitly call each function that you need the compiler to generate.
Note this now affects Android because Google requires 64 bit applications and (as of 2018.3) Unity only supports IL2CPP for building the 64 bit android apps.
I got the same error as zakrzus, but for different types:
08-08 10:05:24.260: E/Unity(15209): ExecutionEngineException: Attempting to call method 'InvokableCallback`2[[System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]::.ctor' for which no ahead of time (AOT) code was generated.
Since this is the constructor, I'm not sure if it's the same generic virtual method problem.
I'm trying to figure out what the System.Single is. (I think it might be float based on https://social.msdn.microsoft.com/Forums/vstudio/en-US/ed7d3355-39a5-4933-b446-2c909997b9c0/what-is-the-use-of-single-data-type-in-c?forum=netfxbcl)
This is the full stack trace that I could get:
08-08 10:05:24.260: E/Unity(15209): ExecutionEngineException: Attempting to call method 'InvokableCallback`2[[System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]::.ctor' for which no ahead of time (AOT) code was generated.
08-08 10:05:24.260: E/Unity(15209): at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0
08-08 10:05:24.260: E/Unity(15209): at System.RuntimeType.CreateInstanceImpl (System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes, System.Threading.StackCrawlMark& stackMark) [0x00000] in <00000000000000000000000000000000>:0
08-08 10:05:24.260: E/Unity(15209): at System.Activator.CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[]
So the error happens here: https://github.com/Siccity/SerializableCallback/blob/84bf6a7f8840be6d4061369d123b3a254a42ae95/SerializableCallbackBase.cs#L42
Another potential cause: https://forum.unity.com/threads/il2cpp-no-constructor-found-for-system-resources-runtimeresourceset.349940/
Basically, the code stripper could be removing the constructor of InvokableCallback and we could add a link.xml file to preserve it. This thread doesn't get resolved and the error/build is slightly different. So I'm not sure if this is the issue.
I think since the constructor of InvokableCallback is called via reflection, IL2CPP never notices the constructor is needed so strips the constructor away. Then at runtime it can't find it.
This could only be a problem with generics of value types.
Either way, we can manage the bytecode stripping with this: https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html . (making the link.xml file as described in the protobuf example.)
So the link.xml change wasn't necessary. Here's how I fixed these errors in my project:
For every error like:
ExecutionEngineException: Attempting to call method 'InvokableCallback`2[[System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]::.ctor' for which no ahead of time (AOT) code was generated.
This means IL2CPP never generated a constructor for the InvokableCallback of the type listed. So, we must hard-code create the class that matches the types given and call the constructor.
So to fix this one, I added code in my repo (doesn't matter what class it's in, so I'd recommend it's own AotGenerationFixer class):
private static void OnlyForIL2CPPAOT() { new FloatStringInvokable(4.0f, ""); } class FloatStringInvokable : InvokableCallback<float, string> { public FloatStringInvokable(object target, string methodName) : base(target, methodName) { } }
I made an InvokableCallback<float, string> because the exception listed this type specifically was missing. ('InvokableCallback`2[[System.Single, ...],[System.String, ...]]::.ctor') (Note: System.Single = float)
I'm not sure how to anticipate when these errors show up. (I never used any Serializable or InvokableCallbacks like these as far as I'm aware.) So for now, the best approach is to build, launch on phone, see what errors you get, and create the necessary class to fix the error, rinse/repeat.
Hope this helps someone!
Here are some links to get around the dead / unused code elimination feature:
If you experience problems with the editor:
And in order to preserve code (e.g. methods, classes etc) you can define your own PreserveAttribute and use that for annotating the respective classes, methods or constructors
More information on this can be found in this comment
See also
Thank you very much :)
Hi, I tried to use dialogue node system on iOS build but when i try run "Event Class" my console shows that exception was thrown in "InvokableCallback" On the last line: (Filename: currently not available on il2cpp Line: -1)
Is there any workround ?