Protobuf-net 尝试 JIT 编译方法'(包装器动态方法)ClassExtensions.StringArray

Posted

技术标签:

【中文标题】Protobuf-net 尝试 JIT 编译方法\'(包装器动态方法)ClassExtensions.StringArray【英文标题】:Protobuf-net Attempting to JIT compile method '(wrapper dynamic-method) ClassExtensions.StringArrayProtobuf-net 尝试 JIT 编译方法'(包装器动态方法)ClassExtensions.StringArray 【发布时间】:2014-06-03 12:22:28 【问题描述】:

用于序列化的 Unity3d protobuf-net。我预编译了我的 RuntimeTypeModel,然后加载它并使用它进行序列化。

ios 上,我仍然收到以下错误:

ExecutionEngineException: Attempting to JIT compile method '(wrapper dynamic-method) ClassExtensions.StringArray:proto_3 (object,ProtoBuf.ProtoWriter)' while running with --aot-only.

  at System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) [0x00000] in <filename unknown>:0 
  at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) [0x00000] in <filename unknown>:0 
  at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) [0x00000] in <filename unknown>:0 
  at System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type delegateType) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Compiler.CompilerContext.BuildSerializer (IProtoSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0 
Rethrow as InvalidOperationException: It was not possible to prepare a serializer for: ClassExtensions.StringArray
  at ProtoBuf.Compiler.CompilerContext.BuildSerializer (IProtoSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.CompiledSerializer..ctor (IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.CompiledSerializer.Wrap (IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Meta.MetaType.CompileInPlace () [0x00000] in <filename unknown>:0 
  at ProtoBuf.Meta.MetaType.get_Serializer () [0x00000] in <filename unknown>:0 
  at ProtoBuf.Meta.RuntimeTypeModel.Serialize (Int32 key, System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <filename unknown>:0 
  at ProtoBuf.ProtoWriter.WriteObject (System.Object value, Int32 key, ProtoBuf.ProtoWriter writer) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.SubItemSerializer.ProtoBuf.Serializers.IProtoSerializer.Write (System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.TagDecorator.Write (System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.ListDecorator.Write (System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.FieldDecorator.Write (System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Serializers.TypeSerializer.Write (System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Meta.RuntimeTypeModel.Serialize (Int32 key, System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Meta.TypeModel.SerializeCore (ProtoBuf.ProtoWriter writer, System.Object value) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value, ProtoBuf.SerializationContext context) [0x00000] in <filename unknown>:0 
  at ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value) [0x00000] in <filename unknown>:0 
  at RouterConfig.Save (System.String configFileName) [0x00000] in <filename unknown>:0 
  at RouterConfig.SaveRun () [0x00000] in <filename unknown>:0 
  at Console.Update () [0x00000] in <filename unknown>:0 

这是我的课:

using ProtoBuf;

namespace ClassExtensions

    //this class will allow use to Serialize a List<StringArray>
    [ProtoContract]
    public class StringArray
    
        [ProtoMember(1)] public string[] items  get; set; 
        public StringArray() 
        public StringArray(string[] c) this.items = c;
        //conversion from string[] to StringArray 
        public static implicit operator StringArray(string[] a)
         return new StringArray(a); 
        //conversion from StringArray to string[] 
        public static implicit operator string[](StringArray a)
         return a.items; 
        //conversion from StringArray to string[] 


        public static string[][] ConvertToStringDoubleArray(List<StringArray> a)
        
            List<string[]> b = new List<string[]>();
            foreach(StringArray c in a)
                b.Add(c.items);
            return b.ToArray();
        
        //used to allow indexing...
        public string this[int i]
        
            get  return this.items[i]; 
            set  this.items[i] = value; 
        
    

编译成 DLL:

RuntimeTypeModel rModel = TypeModel.Create();

rModel.AllowParseableTypes = true;
rModel.AutoAddMissingTypes = true;

rModel.Add(typeof(StringArray), true);

rModel.Compile("MySerializer", "MySerializer.dll");

根据我的研究,这应该可行。我在这里遗漏了什么吗?

【问题讨论】:

【参考方案1】:

想通了。问题是虽然我预编译了它,但 protobuf 试图再次编译。将此行添加到代码中即可修复它。

rModel.AutoCompile = false;

【讨论】:

以上是关于Protobuf-net 尝试 JIT 编译方法'(包装器动态方法)ClassExtensions.StringArray的主要内容,如果未能解决你的问题,请参考以下文章

(Xamarin iOS):ExecutionEngineException - 在仅 aot 模式下运行时尝试 JIT 编译方法

如何使用 monotouch 编译库(出现错误:尝试使用 --aot-only 进行 JIT 编译)

一种针对JavaScript引擎JIT编译器的模糊测试方法

Xamarin IOS LexDB Save - 尝试 JIT 编译的异常(包装器委托调用)

jit编译原理

JVM之JIT编译器实战