Quelle est la différence entre les structures contenant bool vs uint lorsque vous utilisez PInvoke?
Question
Ok, je suis maintenant très confus. Après ma dernière question , plusieurs personnes ont fait part de leurs commentaires sur le changement de bool en uint. J'ai vérifié qu'elles étaient de la même taille en:
Console.WriteLine("sizeof bool = {0}", Marshal.SizeOf(typeof(bool)));
Console.WriteLine("sizeof uint = {0}", Marshal.SizeOf(typeof(uint)));
Qui imprime bien sûr:
sizeof bool = 4
sizeof uint = 4
Cela dit, je suis ensuite tombé en panne et, de toute façon, j'ai essayé leurs suggestions ... Changer un booléen à l'intérieur d'une structure en un uint. Ce que je n'arrive pas à comprendre pour ma vie, c’est pourquoi cela a permis de faire fonctionner ce projet ...
Donc ça marche:
[StructLayout(LayoutKind.Sequential)]
public struct KEY_EVENT_RECORD
{
public bool bKeyDown;
public short wRepeatCount;
public short wVirtualKeyCode;
public short wVirtualScanCode;
public char UnicodeChar;
public int dwControlKeyState;
}
Lorsqu'il est utilisé dans cette structure:
[StructLayout(LayoutKind.Explicit)]
public struct INPUT_RECORD
{
[FieldOffset(0)] public short EventType;
[FieldOffset(4)] public KEY_EVENT_RECORD KeyEvent;
}
Mais dans cette structure, ça casse:
[StructLayout(LayoutKind.Explicit)]
public struct INPUT_RECORD
{
[FieldOffset(0)] public short EventType;
[FieldOffset(4)] public KEY_EVENT_RECORD KeyEvent;
[FieldOffset(4)] public MOUSE_EVENT_RECORD MouseEvent;
[FieldOffset(4)] public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
[FieldOffset(4)] public MENU_EVENT_RECORD MenuEvent;
[FieldOffset(4)] public FOCUS_EVENT_RECORD FocusEvent;
}
Pourtant, lorsque je remplace bool bKeyDown par uint dans la structure KEY_EVENT_RECORD
, il recommence à fonctionner ...
Quelqu'un peut-il expliquer ce comportement, s'il vous plaît?
Je voudrais vraiment connaître le pourquoi afin d'éviter cette fonctionnalité non documentée (bogue) à l'avenir.
La solution 3
Question reformulée avec un nouvel exemple:
Planification booléenne avec LayoutKind. Explicite, s’agit-il d’une panne ou d’échec comme prévu?
Autres conseils
Essayez de définir le type de champ sur bool et d'ajouter l'attribut [MarshalAs (UnmanagedType.Bool)].
[StructLayout(LayoutKind.Sequential)]
public struct KEY_EVENT_RECORD
{
[MarshalAs(UnmanagedType.Bool)]
public bool bKeyDown;
public short wRepeatCount;
public short wVirtualKeyCode;
public short wVirtualScanCode;
public char UnicodeChar;
public int dwControlKeyState;
}
Docs pour MarshalAsAttribute Docs pour UnmanagedType
bools sont 1byte - > sizeof (référence C #)
Voir également Marshaling par défaut pour les types booléens