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

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

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

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

【问题讨论】:

    标签: c# android unity3d 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”。
    猜你喜欢
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    相关资源
    最近更新 更多