“对PInvoke函数的调用使堆栈失衡”

我在visual c#中创建了一个Form应用程序,它使用一个函数来生成鼠标单击,但是我收到以下错误消息:

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. 

我的代码:

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

您的Win32 API声明不正确:’long’映射到.NET Framework中的Int64,对于Windows API调用几乎总是不正确。

用int替换long应该有效:

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

为了将来参考,您可能需要在查找调用API函数的正确方法时检查pinvoke.net – 虽然它不完美,但它会显示mouse_event的正确声明 。

(编辑,2012年3月26日):尽管我提供的声明确实有效,但用uint替换long会更好,因为Win32的DWORD是一个32位无符号整数。 在这种情况下,您将使用有符号整数(因为标志和其他参数都不会大到足以导致符号溢出),但这绝对不是这样。 pinvoke.net声明是正确的,如下所示:

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

这个问题的另一个答案已经提供了这个正确的声明,并且在评论中也指出了uint问题。 我编辑了自己的答案,使其更加明显; 其他SO参与者也应该随时编辑错误的post,BTW。

尝试使用下面的mouse_event signeture。 注意uint而不是long

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

你必须使用uint而不是long

请注意,在Microsoft C / C ++实现中, longint相同,都是32位(即使在64位平台上)。 所以它们实际上是可以互换的。 一个64位的int long long 。 相反,在C#中, int映射到Int32long映射到Int64 。 所以他们不可互换!

那么当P / Invoking时,它会在堆栈上放置5 * 64位/ 8字节= 40个字节。 但本机函数仅使用和清理5 * 32位/ 4字节= 20字节。

就我而言:

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

做了伎俩。