ios - 使用 Protobuf-net,我收到有关 List<Subclassable> 未知线路类型的异常

标签 ios unity-game-engine 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 行,我会收到有关子类的错误。而且,如果我在 Unit 中取出 ProtoMember,它仍然会抛出异常。

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

最佳答案

我的目光立即被吸引:

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

Protobuf 数据不是文本,也不是 UTF-8(尽管 protobuf 数据内的字符串是 UTF-8,巧合) - 因此“解码”它(错误的单词,真的)通过 UTF8 肯定会损坏数据。处理 protobuf 数据的首选方法是二进制 - 例如 byte[] - 就像处理图像数据等一样。但是,如果您需要以文本形式存储或传输它形式,则 Convert.ToBase64StringConvert.FromBase64String 是在文本和二进制之间进行转换的适当机制。请参阅How many ways can you mess up IO?第一节了解更多信息。

关于ios - 使用 Protobuf-net,我收到有关 List<Subclassable> 未知线路类型的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24611339/

相关文章:

iOS Autolayout 调整标签大小和它们之间的空间

ios - 在 swift2 中,UIPageviewController 页面 curl 动画在快速滑动时挂起/卡住

ios - Facebook Unity SDK 6.0 重新请求拒绝权限

c# - 如何在 Unity C# 中为多个游戏对象移动进行多线程处理

c# - 序列化 LinqToSql 生成的实体,保持关系和延迟加载

c# - protobuf-net 支持命名元组吗?

iphone - 变换表格 View

iphone - 在 objective-c 中计算直角三角形的角度

opengl - Unity OpenGL 渲染器

c# - 如何在 protobuf-net 中手动将可选字段添加到类中