Qual è la differenza tra le strutture che contengono bool vs uint quando si utilizza PInvoke?
Domanda
Ok, ora sono molto confuso. Dopo la mia ultima domanda alcune persone hanno commentato sul cambiamento di bool in uint, ho verificato che hanno le stesse dimensioni di:
Console.WriteLine("sizeof bool = {0}", Marshal.SizeOf(typeof(bool)));
Console.WriteLine("sizeof uint = {0}", Marshal.SizeOf(typeof(uint)));
Che ovviamente stampa:
sizeof bool = 4
sizeof uint = 4
Detto questo, poi mi sono rotto e ho provato i loro suggerimenti comunque ... Cambiando un singolo bool all'interno di una struttura in un uint. Quello che non riesco a capire per la mia vita è il motivo per cui questo ha fatto funzionare ...
Quindi funziona:
[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;
}
Se utilizzato in questa struttura:
[StructLayout(LayoutKind.Explicit)]
public struct INPUT_RECORD
{
[FieldOffset(0)] public short EventType;
[FieldOffset(4)] public KEY_EVENT_RECORD KeyEvent;
}
Ma in questa struttura si rompe:
[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;
}
Tuttavia, quando cambio bool bKeyDown in uint nella struttura KEY_EVENT_RECORD
, ricomincia a funzionare ...
Qualcuno può spiegare questo comportamento?
Mi piacerebbe davvero sapere il perché di ciò in modo da poter evitare questa funzione non documentata (aka bug) in futuro.
Soluzione 3
Domanda riformulata con un nuovo campione:
Marshalling booleano con LayoutKind. Esplicito, è rotto o non funziona come previsto?
Altri suggerimenti
Prova a impostare il tipo di campo su bool e aggiungi l'attributo [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;
}
Documenti per MarshalAsAttribute Documenti per UnmanagedType
I bool sono 1byte - > sizeof (Riferimenti per C #)
Inoltre, vedi Marshalling predefinito per tipi booleani