mar*_*khc 4 .net c# marshalling
我正在尝试阅读/编辑暗黑破坏神的保存文件.这里的规格,如果有人感兴趣,但我不认为它与问题有关.
我有一个字节数组,其中包含我正在尝试解析某些结构的文件字节.我已经可以很好地读取文件头了,但是我遇到了任务数据问题.我得到了结构:
[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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
并且函数Im用于执行字节到结构转换:
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;
}
Run Code Online (Sandbox Code Playgroud)
正如我所说,我已经可以单独读取文件头而没有问题,但是当我将任务数据添加到D2SFile结构时,我得到: Could not load type 'MedianXLEditor.QuestCompletationData' from assembly '...' because it contains an object field at offset 10 that is incorrectly aligned or overlapped by a non-object field.
由于没有人回答,我已经发现了什么是错的,我想我应该自己回答,以便任何碰巧在google搜索后结束的人都会有更轻松的时间.
事实证明,你不能有一个从不是4的倍数的偏移开始的数组.
在上面的示例中,QuestCompletationDataHeader长度为10个字节,因此在QuestCompletationData结构上,下一个字段将从位置10开始.下一个字段恰好是QuestData结构,它基本上是一个大数组(现在).因此它会尝试将该数组放在偏移量10,10处不是4的倍数,因此它给出了异常.
我更改了QuestData结构,因此它不在第一个位置使用数组,现在它工作正常.
此外,[MarshalAs(UnmanagedType.Struct)]当编组结构如上所述时使用.我正在使用[MarshalAs(UnmanagedType.LPStruct)],后来又给了我另一个例外.
| 归档时间: |
|
| 查看次数: |
1186 次 |
| 最近记录: |