第一次序列化时Protobuf-net InvalidProgramException

时间:2017-08-29 15:24:09

标签: c# unity3d protobuf-net

我开始了一个小项目,用统一的方式测试protobuf功能。 我试图从不同的按钮序列化序列化一些多态值。当我启动项目时,我总是在按钮单击时出现InvalidProgramException。但所有后续点击都不会导致异常。

我试图谷歌,但一无所获。

完整错误语法为:

InvalidProgramException: Invalid IL code in (wrapper dynamic-method) object:proto_3 (object,ProtoBuf.ProtoWriter): IL_0025: box       0x00000007

这是我用于的一些代码:

[ProtoContract(SkipConstructor = true)]    
public struct NetworkCommandSerializationWrapper
{
    [ProtoMember(1)]
    public IActorNetworkCommand Command;
}

[ProtoContract]
[ProtoInclude(10, typeof(RendererStateNetworkCommand))]
[ProtoInclude(20, typeof(RD2))]
public interface IActorNetworkCommand
{
    void Execute();
}

[ProtoContract]
public struct RendererStateNetworkCommand : IActorNetworkCommand
{
    public RendererStateNetworkCommand(RendererStateNetworkData i)
    {
        data = i;
    }

    public void Execute()
    {    
    }

    [ProtoMember(11)]
    public RendererStateNetworkData data;
}

public struct RD2 : IActorNetworkCommand
{
    public void Execute()
    {
    }

    [ProtoMember(21)]
    public int data3;
}

public interface ISerializator<TResult>
{
    TResult SerializeObject<T>(T serializableObject);
    T DeserializeObject<T>(TResult serilizedBytes);
}

public class BinarySerializator : ISerializator<byte[]>
{
    public byte[] SerializeObject<T>(T serializableObject)
    {
        Debug.LogFormat("SerializeObject {0}, {1}", serializableObject, serializableObject.GetType());

        using (MemoryStream mStream = new MemoryStream())
        {
            Serializer.Serialize<T>(mStream, serializableObject);
            return mStream.ToArray();
        }
    }
    public T DeserializeObject<T>(byte[] serilizedBytes)
    {
        using (MemoryStream mStream = new MemoryStream(serilizedBytes))
        {
            return Serializer.Deserialize<T>(mStream);
        }
    }
}

public abstract class ButtonContextBase : MonoBehaviour, IButtonContext
{
    public virtual void OnButtonClick()
    {
        ClickHandler.Instance.OnClick(SerializeData(GetCommand()));        
    }

    protected abstract IActorNetworkCommand GetCommand();

    protected byte[] SerializeData(IActorNetworkCommand command)
    {
        if (command == null)
        {
            Debug.LogErrorFormat("Command is null!");
            return null;
        }

        var wrapper = new NetworkCommandSerializationWrapper() { Command = command };
        Debug.LogFormat("SerializeData {0}, {1}", command, wrapper.Command);
        var data = SerializatorSingletone.Instance.SerializeObject(wrapper);

        return data;
    }
}

public class RendererStateContext : ButtonContextBase
{
    protected override IActorNetworkCommand GetCommand()
    {
        var command = new RendererStateNetworkCommand() { data = new RendererStateNetworkData() { sh_State = (ushort)ERendererState.Idle } };
        return command;
    }
}

public class SerializatorSingletone : MonoBehaviour
{
    private static BinarySerializator m_Instance;

    public static BinarySerializator Instance
    {
        get
        {
            if (m_Instance == null)
            {
                m_Instance = new BinarySerializator();
            }

            return m_Instance;
        }
    }
}

完整异常输出:

InvalidProgramException: Invalid IL code in (wrapper dynamic-method) object:proto_3 (object,ProtoBuf.ProtoWriter): IL_0025: box       0x00000007

System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, System.Boolean throwOnBindFailure, System.Boolean allowClosed) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:282)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, System.Boolean throwOnBindFailure) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:297)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Delegate.cs:302)
System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type delegateType) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs:175)
ProtoBuf.Compiler.CompilerContext.BuildSerializer (ProtoBuf.Serializers.IProtoSerializer head, ProtoBuf.Meta.TypeModel model) (at c:/Dev/protobuf-net/protobuf-net/Compiler/CompilerContext.cs:63)
Rethrow as InvalidOperationException: It was not possible to prepare a serializer for: IActorNetworkCommand


ProtoBuf.Compiler.CompilerContext.BuildSerializer (ProtoBuf.Serializers.IProtoSerializer head, ProtoBuf.Meta.TypeModel model) (at c:/Dev/protobuf-net/protobuf-net/Compiler/CompilerContext.cs:70)
ProtoBuf.Serializers.CompiledSerializer..ctor (ProtoBuf.Serializers.IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) (at c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:43)
ProtoBuf.Serializers.CompiledSerializer.Wrap (ProtoBuf.Serializers.IProtoTypeSerializer head, ProtoBuf.Meta.TypeModel model) (at c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:32)
ProtoBuf.Meta.MetaType.CompileInPlace () (at c:/Dev/protobuf-net/protobuf-net/Meta/MetaType.cs:1587)
ProtoBuf.Meta.MetaType.get_Serializer () (at c:/Dev/protobuf-net/protobuf-net/Meta/MetaType.cs:386)
ProtoBuf.Meta.RuntimeTypeModel.Serialize (System.Int32 key, System.Object value, ProtoBuf.ProtoWriter dest) (at c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:752)
ProtoBuf.ProtoWriter.WriteObject (System.Object value, System.Int32 key, ProtoBuf.ProtoWriter writer) (at c:/Dev/protobuf-net/protobuf-net/ProtoWriter.cs:46)
ProtoBuf.BclHelpers.WriteNetObject (System.Object value, ProtoBuf.ProtoWriter dest, System.Int32 key, ProtoBuf.BclHelpers+NetObjectOptions options) (at c:/Dev/protobuf-net/protobuf-net/BclHelpers.cs:539)
(wrapper dynamic-method) NetworkCommandSerializationWrapper:proto_1 (object,ProtoBuf.ProtoWriter)

ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Write (System.Object value, ProtoBuf.ProtoWriter dest) (at c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:53)
ProtoBuf.Meta.RuntimeTypeModel.Serialize (System.Int32 key, System.Object value, ProtoBuf.ProtoWriter dest) (at c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:752)
ProtoBuf.Meta.TypeModel.SerializeCore (ProtoBuf.ProtoWriter writer, System.Object value) (at c:/Dev/protobuf-net/protobuf-net/Meta/TypeModel.cs:186)
ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value, ProtoBuf.SerializationContext context) (at c:/Dev/protobuf-net/protobuf-net/Meta/TypeModel.cs:217)
ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value) (at c:/Dev/protobuf-net/protobuf-net/Meta/TypeModel.cs:201)
ProtoBuf.Serializer.Serialize[T] (System.IO.Stream destination, T instance) (at c:/Dev/protobuf-net/protobuf-net/Serializer.cs:87)
RuntimeSerialization.BinarySerializator.SerializeObject[T] (T serializableObject) (at Assets/Scripts/Serialization/BinarySerializator.cs:21)
ButtonContextBase.SerializeData (IActorNetworkCommand command) (at Assets/Scripts/Button/Context/ButtonContextBase.cs:27)
ButtonContextBase.OnButtonClick () (at Assets/Scripts/Button/Context/ButtonContextBase.cs:12)
ButtonBehaviour.OnButtonClick () (at Assets/Scripts/Button/ButtonBehaviour.cs:20)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:154)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:637)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:773)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:52)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:36)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:45)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261)
UnityEngine.EventSystems.EventSystem:Update()

0 个答案:

没有答案