使用 Protobuf-net,我得到一个关于 List<Subclassable> 的未知线路类型的异常
Posted
技术标签:
【中文标题】使用 Protobuf-net,我得到一个关于 List<Subclassable> 的未知线路类型的异常【英文标题】:Using Protobuf-net, I get an exception about an unknown wire-type with List<Subclassable> 【发布时间】:2014-07-07 13:07:37 【问题描述】:我已经开始将我们的 Unity/ios 游戏转换为使用 Protobuf-net 保存状态。看起来一切正常,直到我将此实例变量添加到 GameState
[ProtoMember(10)]
public List<Unit> fUnits;
单位是
[ProtoContract]
[ProtoInclude(21, typeof(ArtilleryUnit))]
[ProtoInclude(22, typeof(CavalryArtilleryUnit))]
[ProtoInclude(23, typeof(CavalryUnit))]
[ProtoInclude(24, typeof(InfantryUnit))]
[Serializable]
public class Unit : IActionHandler
这是我序列化的第一个子类。我正在编写后立即通过反序列化来测试我的代码
using (Stream memoryStream = new MemoryStream())
byte[] data = System.Text.Encoding.UTF8.GetBytes(readText);
memoryStream.Write(data, 0, data.Length);
memoryStream.Position = 0;
WBTSSerializer deserializer = new WBTSSerializer();
testState = new GameState();
deserializer.Deserialize(memoryStream, testState, typeof(GameState));
我明白了
ProtoBuf.ProtoException: Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see http://***.com/q/2152978/23354
at ProtoBuf.ProtoReader.SkipField () [0x00000] in <filename unknown>:0
at WBTSSerializer.Read (wbts.Unit , ProtoBuf.ProtoReader ) [0x00000] in <filename unknown>:0
at WBTSSerializer.Read (wbts.GameState , ProtoBuf.ProtoReader ) [0x00000] in <filename unknown>:0
at WBTSSerializer.Deserialize (Int32 , System.Object , ProtoBuf.ProtoReader ) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoBuf.ProtoReader reader, System.Type type, System.Object value, Boolean noAutoCreate) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream source, System.Object value, System.Type type, ProtoBuf.SerializationContext context) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream source, System.Object value, System.Type type) [0x00000] in <filename unknown>:0
at wbts.Game.SaveGame (System.String filename) [0x000c1] in /Users/david/Shenandoah/WBTS/wbts/wbts/Game.cs:620
不用说,我已经检查过是否覆盖(这是一个全新的文件)。而且,如果我取出ProtoMember(10)
,它就不会抛出。
如果我取出 ProtoInclude
行,我会收到关于子类的错误。而且,如果我在Unit
中取出ProtoMember
,它仍然会抛出。
如果重要的话,我目前只是从 Xamarin 运行它(在 Mac OS X 上——我是一名 iOS 开发人员)。但这只是为了便于测试,我已经设法用足够多的棒击中 Protobuf-net 以使其在 iPad 上运行。
【问题讨论】:
【参考方案1】:我的目光立刻被吸引到:
byte[] data = System.Text.Encoding.UTF8.GetBytes(readText);
Protobuf 数据不是文本,也不是 UTF-8(虽然 inside protobuf 数据的字符串是 UTF-8,巧合) - 因此“解码”它(错误的词,真的)通过UTF8
将保证您损坏数据。处理 protobuf 数据的首选方式是二进制 - 例如,byte[]
- 就像处理图像数据等一样。但是,如果您需要以文本形式存储或传输它,那么 Convert.ToBase64String
和Convert.FromBase64String
是在文本和二进制之间进行转换的适当机制。请参阅How many ways can you mess up IO? 的第一部分了解更多信息。
【讨论】:
几乎可以肯定的是,我们的 XML 序列化中的 .NET 无知复制粘贴。不幸的是,一旦我使用了正确的 byte[] 处理(包括 Mono 本身崩溃),我就开始遇到其他错误,然后我忘记了获取 iOS DLL 所经历的步骤。所以现在我回到 .NET 的 XML 序列化。以上是关于使用 Protobuf-net,我得到一个关于 List<Subclassable> 的未知线路类型的异常的主要内容,如果未能解决你的问题,请参考以下文章