使用Protobuf-net,我得到一个关于List <subclassable> </subclassable>的未知线型的例外

时间:2014-07-07 13:07:38

标签: ios unity3d protobuf-net

我已经开始将我们的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://stackoverflow.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行,我会收到有关子类的错误。而且,如果我在ProtoMember内取出Unit,它仍然会抛出。

如果重要的话,我目前只是从Xamarin运行它(在Mac OS X上 - 我是iOS开发人员)。但这只是为了便于测试,我已经设法用足够的棒来打击Protobuf-net以使其在iPad上运行。

1 个答案:

答案 0 :(得分:2)

我的眼睛立即被吸引到:

byte[] data = System.Text.Encoding.UTF8.GetBytes(readText);

Protobuf数据不是文本,并且不是UTF-8(虽然 protobuf数据中的字符串是巧合的UTF-8) - 因此“解码”它(错误的单词,真的)通过UTF8将保证您损坏数据。处理protobuf数据的首选方法是二进制 - 例如,byte[] - 与图像数据一样。但是,如果您需要以文本形式存储或传输它,那么{{ 1}}和Convert.ToBase64String是在文本和二进制文件之间进行转换的适当机制。有关详细信息,请参阅How many ways can you mess up IO?的第一部分。