"PInvoke function call unbalanced stack"

I created a Form application in visual C # that uses a function to generate a mouse click, but I received the following error message:

A call to PInvoke function '...Form1::mouse_event' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature. 

My code is:

 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo); private const int MOUSEEVENTF_LEFTDOWN = 0x02; private const int MOUSEEVENTF_LEFTUP = 0x04; ... void GenerateMouseClick(int x, int y) { Cursor.Position = new Point((int)x, (int)y); mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, Cursor.Position.X, Cursor.Position.Y, 0, 0); } 
+6
source share
4 answers

Your Win32 API declaration is incorrect: long cards for Int64 in the .NET Framework, which is almost always incorrect for Windows API calls.

Replacing long with int should work:

public static extern void mouse_event (int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

For future reference, you can check pinvoke.net whenever you are looking for the right way to call API functions - although this is not ideal, the correct declaration for mouse_event would be shown.

(EDIT, March 26, 2012): And although the declaration I provided does work, replacing long with uint will be even better since Win32 DWORD is a 32-bit unsigned integer. In this case, you will avoid using a signed integer (since neither flags nor other arguments will ever be large enough to cause a sign to overflow), but this is definitely not always the case. The pinvoke.net declaration is correct, as shown below:

 public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo); 

Another answer to this question has already been given by this correct announcement, and the uint problem has also been noted in the comments. I edited my own answer to make this more obvious; other SO members should also always freely edit incorrect messages, BTW.

+13
source

Try using the following mouse_event mark. Note uint instead of long .

 static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo); 
+4
source

You should use uint instead of long .

Please note that in the Microsoft C / C ++ implementation, long same as int , and both are 32-bit (even on a 64-bit platform). Therefore, they are almost interchangeable. 64-bit int - long long . In contrast, in C #, int maps to Int32 , and long maps to Int64 . Therefore, they are not interchangeable!

So what happens when P / Invoking, it pushes 5 * 64 bits / 8 bytes = 40 bytes onto the stack. But the built-in function uses and clears 5 * 32 bits / 4 bytes = 20 bytes.

+4
source

In my case:

 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)] public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo); 

did the trick.

0
source

Source: https://habr.com/ru/post/911579/


All Articles