A customer reported having problems developing the correct
p/invoke signature for the
INPUT
structure.
“The code works on 32-bit machines, but on 64-bit machines,
the call to SendInput
returns
ERROR_INVALID_PARAMETER
.”
The sample code included the lines
INPUT[] inputs = new INPUT[1]; inputs[0].type = INPUT_KEYBOARD; ... int size = Marshal.SizeOf(inputs[0]); if (!SendInput(1, ref inputs, size)) { Console.WriteLine("Failed with error {0}", GetLastError()); }
My response was simply, “I bet you are passing the wrong structure size. Note that on 64-bit Windows, the alignment of the inner structures is 8-byte rather than 4-byte. Write a C++ program that does the same thing and compare.”
The customer decided to read only the first sentence of my reply,
possibly the second, and ignore the third.
“So what size should the INPUT
structure be on 64-bit
machines?”
There are a few ways you can go about finding out the size of a structure.
One method is to ask Raymond. This may work, but it makes Raymond rather grumpy since it demonstrates that you are lazy and just want the answer handed to you with no effort (or demonstration of understanding) on your part.
Another method is to sit down with the structure definition
and work out the size on a piece of paper,
bearing in mind that various #pragma pack
directives
can change how the structure packing is applied.
But the easiest way to get the size of a structure is to use
the sizeof
operator, because that is after all
the method the compiler uses.
To get the same value as the C++ compiler,
just ask the C++ compiler!
#include <windows.h> #include <stdio.h> #include <stddef.h> int __cdecl main(int argc, char **argv) { printf("the size is %d\n", sizeof(INPUT)); printf("the offset of mi is %d\n", offsetof(INPUT, mi)); return 0; }
You can now use this amazing technique to answer wolf550e’s question:
SSE types require 16-byte alignment. I guess they aren’t used in the Windows SDK? How about directX or something where they are used?
0 comments