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?的主要内容,如果未能解决你的问题,请参考以下文章

AWS S3 Java SDK:以编程方式检测时间/时钟偏差?

C# 编译器如何检测 COM 类型?

使用 C# 在 Windows 上检测防病毒软件 [关闭]

长城在历史上起到过哪些有据可考的实际作用?

从 C# 检测关于 powerpoint 形状的事件

Hooks 错误:在 Windows 上使用 NextJS 或 ReactJS 的 Hook Call 无效