Prenons le cas où je dois m'assurer qu'une classe/structure est mappée en mémoire d'une manière très spécifique, probablement en raison de la nécessité de respecter un protocole externe :
[StructLayout(LayoutKind.Sequential, Pack=1)]
public class SYSTEM_INFO
{
public ulong OemId;
public ulong PageSize;
public ulong ActiveProcessorMask;
public ulong NumberOfProcessors;
public ulong ProcessorType;
}
J'ai ensuite pensé à faire une "superposition" (est-ce un terme approprié ?) pour pouvoir accéder directement à la mémoire :
[StructLayout(LayoutKind.Explicit)]
public class SYSTEM_INFO
{
[FieldOffset(0)] public byte[] Buffer = new byte[40]; //overlays all the bytes, like a C union
[FieldOffset(0)] public ulong OemId;
[FieldOffset(8)] public ulong PageSize;
[FieldOffset(16)] public ulong ActiveProcessorMask;
[FieldOffset(24)] public ulong NumberOfProcessors;
[FieldOffset(32)] public ulong ProcessorType;
}
Mais cela prend beaucoup de temps et est source d'erreurs (si quelque chose change, je peux facilement me tromper en mettant à jour toutes les données de la base de données). FieldOffset
) - et il a été souligné qu'elle n'est en fait pas valable pour des raisons que je ne comprends pas entièrement :
Exception non gérée. System.TypeLoadException : Impossible de charger le type SYSTEM_INFO2' de l'assemblage 'a2bbzf3y.exe, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' parce qu'il contient un champ d'objet à l'offset 0 qui est incorrectement aligné ou recouvert par un champ champ non-objet. Commande terminée par le signal 6
Est-il possible de combiner les deux approches ? Buffer
recouvre les membres, mais tous les membres sauf Buffer
sont alignés automatiquement, séquentiellement, sans remplissage ? Je n'arrive pas à savoir, d'après la documentation, si cela est autorisé ou non, et je peux forcer le décalage de certains membres seulement, les autres étant décidés automatiquement.