- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试读取/编辑暗黑破坏神的保存文件。规范书 here ,如果有人感兴趣,但我认为这与问题无关。
我有一个字节数组,其中包含我试图解析为某些结构的文件字节。我已经可以很好地读取文件头了,但我在处理任务数据时遇到了问题。我得到了结构:
[StructLayout(LayoutKind.Explicit, Size = 10, Pack = 1)]
public struct QuestCompletationDataHeader {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
[FieldOffset(0)]
public string Identifier;
[FieldOffset(4)]
uint _0x0004;
[FieldOffset(8)]
short _0x008;
}
[StructLayout(LayoutKind.Explicit, Size = 96, Pack = 1)]
public struct QuestData {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96, ArraySubType = UnmanagedType.U1)]
[FieldOffset(0)]
byte[] _0x0000; //Irrelevant for now.
}
[StructLayout(LayoutKind.Explicit, Size = 298, Pack = 1)]
public struct QuestCompletationData {
[MarshalAs(UnmanagedType.LPStruct)]
[FieldOffset(0)]
QuestCompletationDataHeader Header;
[MarshalAs(UnmanagedType.LPStruct)]
[FieldOffset(10)]
QuestData NormalQuests;
[MarshalAs(UnmanagedType.LPStruct)]
[FieldOffset(106)]
QuestData NightmareQuests;
[MarshalAs(UnmanagedType.LPStruct)]
[FieldOffset(202)]
QuestData HellQuests;
}
D2SFile 类:
[StructLayout(LayoutKind.Explicit, Size = 638, Pack = 1)]
public struct D2SFile {
[MarshalAs(UnmanagedType.LPStruct)]
[FieldOffset(0)]
public D2SHeader Header;
[MarshalAs(UnmanagedType.LPStruct)]
[FieldOffset(335)]
public QuestCompletationData Quests;
}
我用来执行字节到结构转换的函数:
public static D2SFile ByteArrayToD2SFile(byte[] bytes) {
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
D2SFile stuff = (D2SFile)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(D2SFile));
handle.Free();
return stuff;
}
正如我所说,我已经可以毫无问题地单独读取文件头,但是当我将任务数据添加到 D2SFile 结构时,我得到:Could not load type 'MedianXLEditor.QuestCompletationData' from assembly '.. .' 因为它在偏移量 10 处包含一个对象字段,该对象字段未正确对齐或与非对象字段重叠。
最佳答案
由于没有人回答,而且我已经发现出了什么问题,所以我认为我应该自己回答,这样任何在谷歌搜索后碰巧来到这里的人都会更轻松一些。
事实证明,您不能让数组的起始偏移量不是 4 的倍数。
在上面的示例中,QuestCompletationDataHeader
的长度为 10 个字节,因此在 QuestCompletationData
结构中,下一个字段将从位置 10 开始。下一个字段恰好是QuestData
结构,它基本上是一个大数组(目前)。所以它会尝试将该数组放在偏移量 10 处,因为 10 不是 4 的倍数所以它会给出异常。
我更改了 QuestData
结构,因此它不在第一个位置使用数组,现在它工作正常。
此外,在像上面那样编码结构时使用 [MarshalAs(UnmanagedType.Struct)]
。我使用的是 [MarshalAs(UnmanagedType.LPStruct)]
,后来又给了我另一个异常。
关于c# - 在显式结构上出现 "incorrectly aligned or overlapped by non-object"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28059323/
我是一名优秀的程序员,十分优秀!