J'essaye de désérialiser une structure, et je reçois une exception AV dans PtrToStructure. La seule ride est que c'est une structure de longueur variable, donc j'ai besoin d'ajuster la longueur avant de désérialiser. Voici mon code, y a-t-il quelque chose qui cloche? La structure ne contient que des tableaux entiers/courts/octets, rien d'extraordinaire.Violation d'accès dans Marshal.PtrToStructure
les données entrantes sont 374 octets, et j'ai besoin de l'ajuster pour correspondre à la structure de données de 576 octets. Fondamentalement, le paquet entrant a un dernier champ plus court que le maximum possible, ce qui est normal.
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);
//...
}
Ma structure ressemble à ceci:
[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;
}
Avec le dernier paramètre (option) est un champ de longueur variable maximale de 340 octets (normalement plus courtes)
C'est probablement une faute de frappe, mais ne devriez-vous pas utiliser MyPacket au lieu de MyData lorsque vous appelez Marshal.PtrToStructure? –
Pourquoi ne pas simplement utiliser BinaryReader, puisque vous connaissez tous les décalages? Vous êtes en train de copier la mémoire et de passer de la mémoire gérée à la mémoire non gérée juste pour convertir le tableau d'octets receivedData à la structure qui, à en juger par le code ici, n'est pas utilisée par le code non managé. – liggett78
Oui, c'était une faute de frappe que j'ai introduite lors de la simplification du code pour publication. Désolé pour ça! Je l'ai corrigé. Je vais essayer le BinaryReader, mais j'aimerais quand même savoir ce que je fais de mal ci-dessus. :) –