Unity中使用的Protobuf-net序列化程序提供无效的IL代码IL_0035:调用0x06000001

时间:2015-05-26 20:48:39

标签: c# unity3d protobuf-net

使用Unity 5.0.1f1,protobuf-net r668。

我使用Visual Studio 2013设置了一个protobuf序列化程序dll,设置为框架“Unity .Net 3.5子集基类库”(我也尝试过.Net 3.5,结果相同)。我有4个父类数据类型要序列化:两个相当简单的类型,两个更复杂的一些泛型。两个简单的序列化没有问题,而另外两个给我以下错误:

    for (var i: Number = 0; i < mySaveNewT.data.myNText; ++i) {
            newText = new tbox();
            newText.x = -220;
            newText.y = -513 + i * 69 + 0 * 3.8;
            VWD.addChild(newText);
    }

通过设置Exception saving savegame: Invalid IL code in NVSavegameSerializer:Write (CityBuilder.CBMap/InventoryEntryArray,ProtoBuf.ProtoWriter): IL_0035: call 0x06000001 at NVSavegameSerializer.Write (CityBuilder.Buildings , ProtoBuf.ProtoWriter ) [0x00000] in <filename unknown>:0 at NVSavegameSerializer.Write (CityBuilder.CBMap , ProtoBuf.ProtoWriter ) [0x00000] in <filename unknown>:0 at NVSavegameSerializer.Serialize (Int32 , System.Object , ProtoBuf.ProtoWriter ) [0x00000] in <filename unknown>:0 at ProtoBuf.Meta.TypeModel.SerializeCore (ProtoBuf.ProtoWriter writer, System.Object value) [0x00000] in <filename unknown>:0 at ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value, ProtoBuf.SerializationContext context) [0x00000] in <filename unknown>:0 at ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value) [0x00000] in <filename unknown>:0 at Nova.NVBSavegame.DoSave () [0x001ed] in C:\...\NVBSavegame.cs:118 ,我尝试使用编译器选项来定位.Net1而不是.Net2,但结果是相同的。

以下是异常中提到的地方的片段(InventoryEntryArray只是因为Unity无法序列化数组阵列而存在):

MetaDataVersion = 0x10000;

以下是dll的生成方式:

[Serializable][ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class CBMap
{
    ...
    [Serializable][ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
    public struct InventoryEntryArray
    {
        public CBMap.InventoryEntry[] a;
        public CBMap.InventoryEntry this[int i] { get { return a[i]; } set { a[i] = value; } }
        public InventoryEntryArray(int count) { a = new CBMap.InventoryEntry[count]; }
    }
    ...
    [Serializable][ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
    public struct InventoryEntry : CXPoolIndex
    {
        public int _index;
        public int Index { get { return _index; } set { _index = value; } }
        public static bool operator==(InventoryEntry a, InventoryEntry b) { return a._index == b._index; }
        public static bool operator!=(InventoryEntry a, InventoryEntry b) { return !(a == b); }
        public override bool Equals(System.Object o) { if (!(o is InventoryEntry)) return false; return this == (InventoryEntry)o; }
        public override int GetHashCode() { return _index; }

        public InventoryEntry(int ix) { _index = ix; }
        ... [some properties, a Reset() function]
    }
    ...
    [Serializable][ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
    public class Buildings
    {
        public CXPool<Building> pool;
        ... [no constructor, other variables, CXPool is an interface]
        public float[] repairFactor;
        [CXSoAFieldConstructor(5)]
        public CBMap.InventoryEntryArray[] inventory;
        [^ here's the field mentioned in the exception]
    }
}

对这个问题有什么看法吗?

谢谢。

编辑:

以下是peverify的结果:

        var model = RuntimeTypeModel.Create();
        model.AutoCompile = false;
        model.AllowParseableTypes = true;
        model.AutoAddMissingTypes = true;

        model.Add(typeof(CXPoolIndex), true)
            .AddSubType(1000, typeof(CBMap.Building))
            .AddSubType(1001, typeof(CBMap.Captain))
            .AddSubType(1002, typeof(CBMap.InventoryEntry))
            .AddSubType(1003, typeof(CBMap.Tile))
        ;
        model.Add(typeof(CXPool<CBMap.Building>), true).AddSubType(1000, typeof(CXPoolSwap<CBMap.Building>));
        model.Add(typeof(CXPool<CBMap.Captain>), true).AddSubType(1001, typeof(CXPoolSwap<CBMap.Captain>));
        model.Add(typeof(CXPool<CBMap.InventoryEntry>), true).AddSubType(1002, typeof(CXPoolSwap<CBMap.InventoryEntry>));
        model.Add(typeof(CXPool<CBMap.Tile>), true).AddSubType(1003, typeof(CXPoolSwap<CBMap.Tile>));
        model.Add(typeof(CBMap), true);
        model.Add(typeof(CBSimulation), true);
        model.Add(typeof(NVSavegame.Data), true);
        model.Add(typeof(NVSavegame.BuildingSave), true);

        string typename = "NVSavegameSerializer";
        var opt = new RuntimeTypeModel.CompilerOptions();
        opt.TypeName = typename;
        opt.OutputPath = typename + ".dll";
        //opt.MetaDataVersion = 0x10000;
        model.Compile(opt);

0 个答案:

没有答案