[英]Access Violation in Marshal.PtrToStructure
我正在嘗試反序列化一個結構,並且在 PtrToStructure 中遇到了 AV 異常。 唯一的問題是這是一個可變長度的結構,所以我需要在反序列化之前調整長度。 這是我的代碼,有什么明顯的錯誤嗎? 該結構僅包含整數/短/字節數組,沒什么特別的。
傳入的數據是 374 字節,我需要調整它以匹配 576 字節的數據結構。 基本上傳入的數據包的最后一個字段比可能的最大值短,這是正常的。
public static ... FromByteArray(byte[] receivedData)
{
int rawsize = Marshal.SizeOf(typeof(MyPacket));
// allocate a new buffer of the maximum size, to help deserialization
byte[] newBuffer = new byte[rawsize];
Array.Copy(receivedData, newBuffer, receivedData.Length);
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.Copy(newBuffer, 0, buffer, rawsize);
/// CRASHES ON NEXT LINE
MyPacketDefinition def = (MyPacketDefinition ) Marshal.PtrToStructure(buffer, typeof(MyPacketDefinition ));
Marshal.FreeHGlobal(buffer);
//...
}
我的結構看起來像這樣:
[StructLayout (LayoutKind.Explicit, Pack=1, Size=576, CharSet=CharSet.Ansi)]
public struct MyPacket
{
[FieldOffset(0)]
public System.Byte Type;
.
. // a few more INT/SHORT fields
.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
[FieldOffset(28)] public System.Byte[] Address;
[MarshalAs(UnmanagedType.LPStr, SizeConst=64)]
[FieldOffset(44)] public System.String Name;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 128)]
[FieldOffset(108)] public System.String SystemData;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 340)]
[FieldOffset(236)] public System.Byte[] Options;
}
最后一個參數 (Option) 是最大 340 字節(通常較短)的可變長度字段
正如Franci在評論中所建議的那樣,我能夠使用這種方法使其工作(盡管我不確定這是否就是他的意思)。
我不知道為什么以另一種方式提高視聽效果,我之前使用該方法沒有任何問題。
byte[] mem = new byte[sizeof(typeof(MyPacketDefinition))];
Array.Copy(mem, receivedData, receivedData.Length);
using (MemoryStream ms = new MemoryStream(mem))
{
using (BinaryReader br = new BinaryReader(ms))
{
byte[] buff = br.ReadBytes(Marshal.SizeOf(typeof(MyPacketDefinition )));
GCHandle handle = GCHandle.Alloc(buff, GCHandleType.Pinned);
try
{
MyPacketDefinition s = (MyPacketDefinition )Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MyPacketDefinition ));
}
finally
{
handle.Free();
}
}
}
有點晚了但是......
為了將 C# 編組與結構內的數組一起使用,您必須將它們聲明為“固定”,否則它們只是指向托管內存的指針,這會造成混亂。
值得注意的是,出於某種原因“固定”是一個不安全的選項,需要您將代碼標記為不安全。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.