use*_*285 2 c# copy marshalling
我有这个结构:
[StructLayout(LayoutKind.Sequential)]
public struct IS
{
public UInt32 ID;
public UInt32 Quality;
public UInt32 Flags;
public UInt32 Flags2;
public UInt32 ContainerSlots;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public Int32[] ItemStatType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public UInt32[] ItemStatValue;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public Int32[] ItemStatUnk1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public Int32[] ItemStatUnk2;
public UInt32 ScalingStatDistribution;
public UInt32 DamageType;
public UInt32 Delay;
public float RangedModRange;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public Int32[] SpellId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public Int32[] SpellTrigger;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public Int32[] SpellCharges;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public Int32[] SpellCooldown;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public Int32[] SpellCategory;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public Int32[] SpellCategoryCooldown;
public UInt32 Bonding;
public string Name;
public string Name2;
public string Name3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public UInt32[] Color;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public UInt32[] Content;
};
Run Code Online (Sandbox Code Playgroud)
我正在尝试从文件中读取字节并struct使用Marshal和GCHandle 将这些字节复制到上面,我的代码如下:
reader = BinaryReader.FromFile(fileName);
m_rows = new List<IS>();
int size = Marshal.SizeOf(typeof(IS));
if(reader.BaseStream.Length < size)
return;
byte[] buffer = new byte[size];
buffer = reader.ReadBytes(size);
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
m_rows.Add((IS)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(IS)));
handle.Free();
Run Code Online (Sandbox Code Playgroud)
但我得到了一个 AccessViolationException : attempt to read or write protected memory
我不知道为什么抛出这个异常.
我没有立即看到这个错误并写了一个小测试程序来重现这个问题.使用二进制搜索来查找问题,重复注释一半字段,直到我将其缩小到:
[StructLayout(LayoutKind.Sequential)]
public struct IS {
public string Name;
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,pinvoke marshaller假定字符串的默认封送来自C字符串,char*.这不可能纠正您从文件中读取的数据,它永远不会包含有效的指针.尝试取消引用指针时会触发AccessViolation.
问题中没有任何提示可以猜测字符串是如何实际序列化到文件中的.在正常的方法是:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct IS {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)]
public string Name;
};
Run Code Online (Sandbox Code Playgroud)
如有必要,请使用十六进制查看器来确定SizeConst的正确值.如果编码异常(不是系统默认页面),则必须将其声明为byte []并使用正确的编码进行转换.
| 归档时间: |
|
| 查看次数: |
2312 次 |
| 最近记录: |