jamescourtney / FlatSharp

Fast, idiomatic C# implementation of Flatbuffers
Apache License 2.0
510 stars 51 forks source link

AOT exception when running a game built with Unity 2021.3 IL2CPP #400

Open bmotamer opened 1 year ago

bmotamer commented 1 year ago

Hello :wave:

I'm getting the following error on 7.2.3 when running a game targeting Linux or Android (potentially iOS too) built with Unity 2021.3, IL2CPP as the scripting backend and IL2CPP Code Generation set to "Faster runtime":

System.ExecutionEngineException: Attempting to call method 'FlatSharp.Compiler.Generated.NC418A0549F80F471EB1C1156FF9E0B4B05EF63AD7CD33F898FED3AB3FA498AFC.Serializer::FlatSharp.Internal.IGeneratedSerializer<MyNamespace.Person>.ParseGreedyMutable<FlatSharp.ArrayInputBuffer>' for which no ahead of time (AOT) code was generated.  Consider increasing the --generic-virtual-method-iterations=1 argument
  at FlatSharp.ArrayInputBuffer.FlatSharp.IInputBuffer.InvokeGreedyMutableParse[TItem] (FlatSharp.Internal.IGeneratedSerializer`1[T] serializer, FlatSharp.Internal.GeneratedSerializerParseArguments& arguments) [0x00000] in <00000000000000000000000000000000>:0 
  at FlatSharp.GeneratedSerializerWrapper`1[T].Parse[TInputBuffer] (TInputBuffer buffer, System.Nullable`1[T] option) [0x00000] in <00000000000000000000000000000000>:0 
  at TestBehavior.Start () [0x00000] in <00000000000000000000000000000000>:0 

So far I have tried:

jamescourtney commented 1 year ago

Unfortunately I'm not a game developer and don't have any experience with Unity, so I can't give you a lot of concrete guidance here. FlatSharp does try to emit a static AotHelper method to give hints to AOT compilers about possible uses of generics.

I wish I could help more here since Unity devs seem to get lots of value out of FlatSharp. Are there any resources you could point me to to help reproduce the problem locally?

If you do manage to figure out the correct annotations for Unity, I'm also happy to adjust the FlatSharp codegen to accommodate.

bmotamer commented 1 year ago

Unfortunately I'm not a game developer and don't have any experience with Unity, so I can't give you a lot of concrete guidance here.

No worries! Even if we can't come up with a solution to this, I hope this issue helps others in a similar situation as me. :smile:

Are there any resources you could point me to to help reproduce the problem locally?

Steps to download the Unity Editor:

  1. Download, install Unity Hub and launch it.
  2. On the left side click on Installs, then on the top right click on Install Editor to install the Unity Editor.
  3. Under "Official releases" pick 2021.3.29f1 or newer and hit Install. This will display a list of modules for you to choose to install.
  4. If you're on Windows, select Windows Build Support (IL2CPP). If you're on Linux, select Linux Build Support (IL2CPP). If you're on MacOS, I believe there should be a similar option there too.
  5. Hit Install. It will now download and install the Editor in the background.
  6. Leave the Unity Hub open.

Steps to set up the test project:

  1. Download the test project and unzip it.
  2. Download FlatSharp.Runtime 7.2.3 from NuGet and unzip it.
  3. Navigate to the unzipped FlatSharp.Runtime folder and then to lib/netstandard2.1 in it.
  4. Move all files from within lib/netstandard2.1 to the Plugins folder sitting inside the unzipped test project folder.
  5. Download System.Runtime.CompilerServices.Unsafe 4.5.3 from NuGet and unzip it.
  6. Navigate to the unzipped System.Runtime.CompilerServices.Unsafe folder and then to lib/netstandard2.0 in it.
  7. Move all files from within lib/netstandard2.0 to the Plugins folder sitting inside the unzipped test project folder.

Steps to open the test project with the Unity Editor:

  1. Go back to the Unity Hub.
  2. On the left side click on Projects, then on the top right click on Open and locate the unzipped test project.
  3. Locate the project window. This step will launch the Unity Editor and load your project.
  4. Make sure that the files you've moved to Plugins are there.

Steps to make a build (and reproduce the issue):

  1. In the Unity Editor on the menu at the top, click on File > Build Settings. This window should appear.
  2. Make sure "Windows, Mac, Linux" is selected under "Platform" and that IL2CPP Code Generation is set to "Faster runtime".
  3. Hit "Build And Run" to make a build and launch the game.
  4. Once it launches, if you see a blue screen with a text that says "Success!" it means there were no errors. You should see "Error: " plus the error message if it failed. It should also create a Error.txt in the project's folder containing the error message displayed on screen.

The code in Assets/Scripts/TestBehavior.cs loads the Assets/Content/Generated/Person.txt file and updates the text displayed on screen during runtime.

The FlatSharp generated code is in Assets/Scripts/Generated/FlatSharp.generated.cs.

jamescourtney commented 1 year ago

Thanks for this! I will try to work through this as I have some time over the next week or so.

yingnierxiao commented 2 months ago

i use unity 2023.4.41f1 has the same .ExecutionEngineException: NotSupportAdjustorThunk GameLogic.Network.FlatSharpNetwork.SendProto (FlatSharp.NetMessage clientMessage, System.Int32 channel) (at <00000000000000000000000000000000>:0) GameCode.DlgLoginLogic.Login () (at <00000000000000000000000000000000>:0) FlatSharp.GeneratedSerializerWrapper1[T].Write[TSpanWriter] (TSpanWriter writer, System.Span1[T] destination, T item) (at <00000000000000000000000000000000>:0)

this code maybe cut . [ExcludeFromCodeCoverage] public static int Write(this ISerializer serializer, byte[] buffer, T item) where T : class { return serializer.Write(buffer.AsSpan(), item); }

njannink commented 1 month ago

@bmotamer / @yingnierxiao any success with getting FlatSharp to work with Unity. For us it seems to work fine when targetting Windows, but when targetting iOs or Android we are getting errors

bmotamer commented 1 month ago

@njannink Try changing IL2CPP Code Generation to Faster (smaller builds) and/or Managed Stripping Level to Minimal if you haven't already.