我开始了一个小项目,用统一的方式测试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()