What is the difference between structures containing bool vs uint when using PInvoke?

半城伤御伤魂 提交于 2019-12-22 22:53:28

问题


Ok, I'm now very confused. After my last question had several people comment about changing bool to uint I verified they are the same size by:

    Console.WriteLine("sizeof bool = {0}", Marshal.SizeOf(typeof(bool)));
    Console.WriteLine("sizeof uint = {0}", Marshal.SizeOf(typeof(uint)));

Which of course prints:

sizeof bool = 4
sizeof uint = 4

That said, I then broke down and gave their suggestions a try anyway... Changing a single bool inside a structure to a uint. What I can't figure out for the life of me is why this made it work...

So this works:

[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;
}

When used in this structure:

[StructLayout(LayoutKind.Explicit)]
public struct INPUT_RECORD
{
    [FieldOffset(0)] public short EventType;
    [FieldOffset(4)] public KEY_EVENT_RECORD KeyEvent;
}

But in this structure it breaks:

[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;
}

Yet when I change bool bKeyDown to uint in the KEY_EVENT_RECORD structure it starts working again...

Can someone please explain this behavior?

I really would like to know the why of it so that I can avoid this undocumented feature (aka bug) in the future.


回答1:


Try setting the field type to bool and add the attribute [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 for MarshalAsAttribute Docs for UnmanagedType




回答2:


bools are 1byte --> sizeof (C# Reference)

Also, see Default Marshaling for Boolean Types




回答3:


Question reworded with a new sample:

Boolean Marshalling with LayoutKind.Explicit, Is this broken or failing as designed?



来源:https://stackoverflow.com/questions/1602899/what-is-the-difference-between-structures-containing-bool-vs-uint-when-using-pin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!