【问题标题】:C# -- PInvokeStackImbalance detected on a well documented function?C#——在有据可查的函数上检测到 PInvokeStackImbalance?
【发布时间】: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 代码。

标签: c# pinvoke


【解决方案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);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-09-03
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 2015-12-07
        • 2019-05-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多