- Home /
Why did my BinarySerialzer stop working?
I have been using the method described here:
http://answers.unity3d.com/questions/971/how-to-scrip-a-save-load-game-option
successfully for many months. Today, I started getting the following error when I try to write a file on the iPod:
ExecutionEngineException: Attempting to JIT compile method 'Serializer__TypeMetadata:.ctor ()' while running with --aot-only.
Any idea why this is happening? The call stack follows:
at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in :0 Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in :0 at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in :0 at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in :0 at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in :0 at System.Activator.CreateInstance (System.Type type) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.CreateMemberTypeMetadata (System.Type type) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetObjectData (System.Object obj, System.Runtime.Serialization.Formatters.Binary.TypeMetadata& metadata, System.Object& data) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObject (System.IO.BinaryWriter writer, Int64 id, System.Object obj) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectInstance (System.IO.BinaryWriter writer, System.Object obj, Boolean isValueObject) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteQueuedObjects (System.IO.BinaryWriter writer) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectGraph (System.IO.BinaryWriter writer, System.Object obj, System.Runtime.Remoting.Messaging.Header[] headers) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph) [0x00000] in :0 at QSerializer.WriteFile[Serializer] (System.String fileName, .Serializer source) [0x00000] in :0 at Player.Write () [0x00000] in :0 at G.Save () [0x00000] in :0 at G.OnLevelWasLoaded () [0x00000] in :0
Answer by Nico de Poel · Jul 24, 2013 at 03:44 PM
We had the same problem with a bit of code that uses a BinaryFormatter to (indirectly) serialize an enum value. The BinaryFormatter (or the ObjectWriter used by it to be more precise) attempts to create its own special brand of type metadata for the value, and for custom value types (like structs or enums defined in your code) it will try to dynamically generate a class for that metadata. Which fails on iOS since it does not support run-time code generation.
Using .NET Reflector, I took a look at the serializer code in question, and found out that the ObjectWriter can use a different code path that doesn't rely on run-time code generation, but on reflection instead. And the code path that it uses is configurable with an environment variable.
Just add the following line to the Awake() function of the MonoBehaviour script that uses the BinaryFormatter:
// Forces a different code path in the BinaryFormatter that doesn't rely on run-time code generation (which would break on iOS).
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
... and the BinaryFormatter should work fine on iOS. In theory, using reflection for type metadata will be a little bit slower than using a precompiled class, but in practice you probably won't notice any difference. And it's better than not working at all.
The SetEnvironmentVariable technique worked perfectly! $$anonymous$$any thanks.
You are a star! this worked for me too and saved me a ton of effort having to convert everything over to some other kind of serialisation.
thanks! it even works for serialization of generic in generic collections
SetEnvironmentVariable worked for me when I had to call
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("xx-XX");
on iOS. Thanks!
Answer by r618 · Nov 22, 2011 at 11:54 PM
not sure about this either
Is there any kind of mono stripping involved ?
If that doesn't help I'd file a bug report and/or implement ISerializer interface ( see e.g. http://forum.unity3d.com/threads/79138-I-love-strippers!-aka-Network-Errors-amp-Build-Stripping-question )
There are many problems/reports like this, I personally ended up using XMLSerializer for now since refactoring or providing custom serializer for all classes would be very tedious and I couldn't find the culprit causing JIT compiling *__TypeMetadata:.ctor () using BinaryFormatter
Answer by magavelis · Sep 26, 2017 at 06:29 PM
I also faced similar issue.. Solved it by changing iOS Scripting Backend setting in Player Settings to IL2CPP