msgpack / msgpack-cli

MessagePack implementation for Common Language Infrastructure / msgpack.org[C#]
http://msgpack.org
Apache License 2.0
834 stars 175 forks source link

iOS AOT runtime error from 0.7.0 version #174

Closed smflt closed 8 years ago

smflt commented 8 years ago

i downloaded (MsgPack.Cli.0.7.0.zip) from page https://github.com/msgpack/msgpack-cli/releases/

but i get aot error. from MessagePackSerializer.Get function so i made new project and made test code. but it's same.

how can i fix it? help!!

unity : 5.3.5 p6 msgpack : 0.7.0 unity-full\MsgPack.dll xcode : 7.3.1 (7D1014) script background : il2cpp, api compatibility level : net2.0

[code]

    [System.Serializable]
    public class testPack
    {
        public int a;
        public string b;
    }

    // Use this for initialization
    void Start () 
    {
        using(System.IO.MemoryStream memStream = new System.IO.MemoryStream ())
        {
            testPack a = new testPack ();
            a.a = 2;
            a.b = "234";

            Debug.Log ("000");
            MessagePackSerializer<testPack> serializer = MessagePackSerializer.Get<testPack> ();
            Debug.Log ("111");
            try
            {

                serializer.Pack (memStream, a);
            }
            catch(System.Exception e)
            {
                Debug.Log (e);
            }

            Debug.Log ("222");

            memStream.Position = 0;
            try
            {
                testPack b = serializer.Unpack (memStream);

                Debug.Log (b.a);
                Debug.Log (b.b);
            }
            catch(System.Exception e)
            {
                Debug.Log (e);
            }

            Debug.Log ("333");

            memStream.Close ();
        }
    }

[error]

ExecutionEngineException: Attempting to call method 'MsgPack.Serialization.SerializationContext::GetSerializer' for which no ahead of time (AOT) code was generated.
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.ReflectionExtensions.InvokePreservingExceptionType (System.Reflection.MethodInfo source, System.Object instance, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.SerializationContext+SerializerGetter.Get (MsgPack.Serialization.SerializationContext context, System.Type targetType, System.Object providerParameter) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.ReflectionSerializers.ReflectionObjectMessagePackSerializer`1[T]..ctor (MsgPack.Serialization.SerializationContext context) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.SerializationContext.GetSerializer[T] (System.Object providerParameter) [0x00000] in <filename unknown>:0 
  at TestCode.Start () [0x00000] in <filename unknown>:0 
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.ReflectionExtensions.InvokePreservingExceptionType (System.Reflection.MethodInfo source, System.Object instance, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.SerializationContext+SerializerGetter.Get (MsgPack.Serialization.SerializationContext context, System.Type targetType, System.Object providerParameter) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.ReflectionSerializers.ReflectionObjectMessagePackSerializer`1[T]..ctor (MsgPack.Serialization.SerializationContext context) [0x00000] in <filename unknown>:0 
  at MsgPack.Serialization.SerializationContext.GetSerializer[T] (System.Object providerParameter) [0x00000] in <filename unknown>:0 
  at TestCode.Start () [0x00000] in <filename unknown>:0 
yfakariya commented 8 years ago

There are two work arounds:

  1. Use MessagePackSerializer.PrepareType<testPack>(). It ensures some code are AOTed. This is easier option.
  2. Use pre generated serializer as here. This wiki will be updated, but usage of mpu.exe can be applied. This is stabler option.
smflt commented 8 years ago

thanks. i get solve from case 1 but MessagePackSerializer.PrepareType<testPack>() have same error. than i change MessagePackSerializer.PrepareType<int>(). it's success.

i wonder why MessagePackSerializer.PrepareType<testPack>() is fail

smflt commented 8 years ago
public enum en
{
    a,
    b,
    c,
    d
};

public class testSubPack
{
    public string hashStr;
    public uint crc;
}
public class testPack
{
    public en e;
    public int a;
    public string b;

    //public testSubPack testpack;

    public Dictionary<string, testSubPack> dicSub = new Dictionary<string, testSubPack> ();
}
MessagePackSerializer.PrepareType<uint>();
MessagePackSerializer.PrepareType<int>();
MessagePackSerializer.PrepareType<en>();

it's success case. i expect, it don't include basic variable.

yfakariya commented 8 years ago

Hmm, I will investigate it. Thank you for reporting!

yfakariya commented 8 years ago

Sorry for delay. I tested in 0.7.1 and Unity 5.3.5.f1 with IL2CPP, this error was not reproduced perfectly, I could work with only PrepareType<en>. Preparing enums are required because enum types are always special. This cannot be resolved, so I will close this issue.