C#——在有据可查的函数上检测到 PInvokeStackImbalance?
Posted
技术标签:
【中文标题】C#——在有据可查的函数上检测到 PInvokeStackImbalance?【英文标题】:C# -- PInvokeStackImbalance detected on a well documented function? 【发布时间】:2010-05-31 13:40:09 【问题描述】:这是我的 ClickMouse() 函数代码:
[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 long MOUSEEVENTF_LEFTDOWN = 0x02;
private const long MOUSEEVENTF_LEFTUP = 0x04;
private const long MOUSEEVENTF_RIGHTDOWN = 0x08;
private const long MOUSEEVENTF_RIGHTUP = 0x10;
private void ClickMouse()
long X = Cursor.Position.X;
long Y = Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
由于某种原因,当我的程序遇到此代码时,它会抛出以下错误消息:
检测到 PInvokeStackImbalance 消息:调用 PInvoke 函数 'WindowsFormsApplication1!WindowsFormsApplication1.Form1::mouse_event' 使堆栈不平衡。这可能是因为托管的 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数匹配 目标非托管签名。
请帮忙?
【问题讨论】:
远离 VB6 声明,它们不适用于 .NET 代码。 【参考方案1】:看起来您的 DllImport 声明是错误的。特别是使用 Int64(longs),而不是 UInt32。
以下是 PInvoke 参考中的一些详细信息:http://www.pinvoke.net/default.aspx/user32.mouse_event
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy,
uint dwData,UIntPtr dwExtraInfo);
【讨论】:
@Scottt 我正在使用 VB 到 C#.Net 升级第三方 .dll。根据其文档,原VB程序中所有参数均为VB6长型。 .Net 升级程序已将它们转换为int
。明显的问题是,有一个密码应该是 8 位,并且超出了 int32 类型的容量。所以我们在 C# 中将其更改为 long。但问题是,当使用尝试访问/修改内存的特定函数时,我遇到了同样的错误。我们还应该使用uint
吗?
文档中的注释:“pInvokeStackImbalance MDA 仅适用于 32 位 x86 平台。”【参考方案2】:
我找到了这个声明
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags,
uint dx,
uint dy,
uint dwData,
IntPtr dwExtraInfo);
【讨论】:
【参考方案3】:我使用 RealGetWindowClass 使用以下格式。
[DllImport("User32", CallingConvention=CallingConvention.Cdecl)]
public static extern int RealGetWindowClass(IntPtr hwnd, StringBuilder pszType, int cchType);
我得到了“PInvokeStackImbalance”异常/错误。但是当我将 CallingConvention 更改为
[DllImport("User32", CallingConvention=CallingConvention.StdCall)]
错误消失了。我在 64 位机器上使用 VS2010。
【讨论】:
Win32 API 函数永远不会是Cdecl
;始终使用StdCall
,这是默认设置。
我使用了 CallingConvention = CallingConvention.Cdecl。错误消失了:)。谢谢【参考方案4】:
修复 PInvokeStackImbalance 错误:
按:CTRL + ALT + E
在“托管调试助手”下取消选中 PInvokeStackImbalance
【讨论】:
【参考方案5】:我将“Cdecl”更改为“StdCall”,但它不起作用。
正如 Scott Weinstein 所说,我们应该使用 int 类型。
[DllImport("user32.dll")]
static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
[Flags]
public enum MouseEventFlags
LEFTDOWN = 0x00000002,
LEFTUP = 0x00000004,
MIDDLEDOWN = 0x00000020,
MIDDLEUP = 0x00000040,
MOVE = 0x00000001,
ABSOLUTE = 0x00008000,
RIGHTDOWN = 0x00000008,
RIGHTUP = 0x00000010
public static void LeftClick(int x, int y)
Cursor.Position = new System.Drawing.Point(x, y);
mouse_event((int)(MouseEventFlags.LEFTDOWN), 0, 0, 0, 0);
mouse_event((int)(MouseEventFlags.LEFTUP), 0, 0, 0, 0);
【讨论】:
以上是关于C#——在有据可查的函数上检测到 PInvokeStackImbalance?的主要内容,如果未能解决你的问题,请参考以下文章