Protobuf-net & IL2CPP - System.Reflection.Emit 不受支持

Posted

技术标签:

【中文标题】Protobuf-net & IL2CPP - System.Reflection.Emit 不受支持【英文标题】:Protobuf-net & IL2CPP - System.Reflection.Emit is not supported 【发布时间】:2019-08-29 16:51:54 【问题描述】:

我对使用 IL2CPP 构建的 protobuf-net 和 android 应用程序有疑问。

当我使用 MONO 而不是 IL2CPP 进行开发时,一切正常。现在我需要使用 IL2CPP 来支持 x64。我不知道 IL2CPP 不支持 System.Reflection.Emit 并且 protobuf-net 正在使用它。

有没有办法让 protobuf-net 与 IL2CPP 一起工作?

【问题讨论】:

【参考方案1】:

我在 ios 上遇到了同样的问题。您必须先编译 ProtoModel。

using Assembly = UnityEditor.Compilation.Assembly;
private static void BuildMyProtoModel()

    RuntimeTypeModel typeModel = TypeModel.Create();

    foreach (var t in GetTypes(CompilationPipeline.GetAssemblies(AssembliesType.Player)))
    
        var contract = t.GetCustomAttributes(typeof(ProtoContractAttribute), false);
        if (contract.Length > 0)
        
            MetaType metaType = typeModel.Add(t, true);

            // support ISerializationCallbackReceiver
            if (typeof(ISerializationCallbackReceiver).IsAssignableFrom(t))
            
                MethodInfo beforeSerializeMethod = t.GetMethod("OnBeforeSerialize");
                MethodInfo afterDeserializeMethod = t.GetMethod("OnAfterDeserialize");

                metaType.SetCallbacks(beforeSerializeMethod, null, null, afterDeserializeMethod);
            

            //add unity types
            typeModel.Add(typeof(Vector2), false).Add("x", "y");
            typeModel.Add(typeof(Vector3), false).Add("x", "y", "z");
        
    

    typeModel.Compile("MyProtoModel", "MyProtoModel.dll"); //build model
    string protoSchema = typeModel.GetSchema(null);//content for .proto file, you can generate a proto file for a specific type by passing it instead of null


private static IEnumerable<Type> GetTypes(IEnumerable<Assembly> assemblies)

    foreach (Assembly assembly in assemblies)
    
        foreach (Type type in AppDomain.CurrentDomain.Load(assembly.name).GetTypes())
        
            yield return type;
        
    

将 MyProtoModel.dll 从根目录复制到插件文件夹。 并像这样使用:

TypeModel typeModel = new MyProtoModel();

我创建了一个小项目 Protobuf-net & Unity:

https://github.com/koshelevpavel/UniBufExample

https://github.com/koshelevpavel/UniBuf

但它只是实验性的,没有任何文档。

MonoBehaviour 小例子:

https://gist.github.com/koshelevpavel/8e2d62053fc79b2bf9e2105d18b056bc

【讨论】:

谢谢。到目前为止,我尝试了here 的步骤,但没有运气,Marc wrote 认为这个解决方案不再好。 我会尝试它并在我让它工作时接受答案。我需要为每个 .proto 文件创建 TypeModel 吗? 您需要调用 typeModel.GetSchema(type),如果 type = null 函数将返回整个模型的 .proto。 我检查了 Unity 文档,在 Unity 2017.4 中我使用的是 CompilationPipeline.GetAssemblies 没有参数。 我更新了我的答案。请检查我的要点链接。将此脚本粘贴到您的项目中,然后在 Unity 编辑器菜单中选择选项卡“Protobuf/Build model”。

以上是关于Protobuf-net & IL2CPP - System.Reflection.Emit 不受支持的主要内容,如果未能解决你的问题,请参考以下文章

IL2CPP

使用 protobuf-net 反序列化 int& 类型

使用 protobuf-net 反序列化不同的列表

我可以为 Protobuf-net 设置一个全局对象工厂吗?

使用 protobuf-net 反序列化具有某些字段的派生类型的对象

使用 ProtoBuf-net 反序列化派生类型(字典)未正确设置对象字段