J'ai donc créé une structure que je veux envoyer en utilisant un simple DatagramSocket.La structure hachée aboutit à OutOfBoundsException en C#
Le code struct est la suivante:
public struct MsgData
{
private readonly int _value;
private readonly string _descr;
public MsgData(string desc, int value)
{
_descr = desc;
_value = value;
}
public int GetValue()
{
return _value;
}
public string GetDescr()
{
return _descr;
}
}
Je procède par la conversion en un tableau d'octets comme ceci:
public static byte[] GetBytes(MsgData message)
{
var size = Marshal.SizeOf(message);
var data = new byte[size];
System.IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(message, ptr, true);
Marshal.Copy(ptr, data, 0, size);
Marshal.FreeHGlobal(ptr);
return data;
}
et le retourner à un struct comme MSGDATA si:
public static MsgData GetMessage(byte[] bytes)
{
var data = new MsgData();
var size = Marshal.SizeOf(data);
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
data = Marshal.PtrToStructure<MsgData>(ptr);
Marshal.FreeHGlobal(ptr);
return data;
}
Cependant, je reçois un:
System.ArgumentOutOfRangeException: 'Requested range extends past the end of the array.'
en essayant de convertir en ligne:
Marshal.Copy(bytes, 0, ptr, size);
Je vais aller avec un simple sérialisation instad maintenant, mais je me demande pourquoi cela ne fonctionne pas comme prévu?
Qu'est-ce que est 'bytes.Length' quand l'exception se produit? – mjwills
Etes-vous sûr que 'bytes' contient suffisamment d'octets? J'ajouterais 'if (bytes.Length! = Size) throw new ArgumentException();' quelque part. – Groo
Il n'est pas clair ce que vous voulez que ce code fasse. D'abord, vous n'avez pas spécifié l'attribut StructLayout sur la structure, auquel cas l'empaquetage n'est pas spécifié (vous pouvez détecter quel emballage sera utilisé en fonction de x86/x64 mais le code apparaîtra comme fragile). De plus, vous ne spécifiez pas les attributs "MarshalAs" sur vos champs, auquel cas votre chaîne ne sera pas vraiment rassemblée. Enfin, vous passez "true" au paramètre fDeleteOld de StructureToPtr mais votre mémoire allouée ne doit pas contenir de structure par défaut. –