【问题标题】:Pinvoke stack imbalance detected检测到 Pinvoke 堆栈不平衡
【发布时间】:2011-10-20 03:09:01
【问题描述】:

我有以下功能:

[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, SPoint lParam);

执行以下代码时,它一直在抱怨 Pinvoke 堆栈不平衡:

SendMessage(EventRichTextBox.Handle, EM_GETSCROLLPOS, 0, OldScrollPoint);

什么会导致这个问题?

这是我的点

  private struct SPoint
    {
        public Int32 x;
        public Int32 y;
    }

和

SPoint OldScrollPoint = default(SPoint);

【问题讨论】:

  • 什么是 SPoint 定义?它应该是一个 IntPtr 或等价物。

标签: stack pinvoke


【解决方案1】:

不能肯定,但一个明显的可能性是您使用的是 64 位机器,而 int 是 wParam 的错误类型。它需要是 64 位进程中的 64 位值。

我们也不知道你是如何声明SPoint的。您应该将指针传递给 POINT 结构。看起来好像你没有这样做。

正确的签名是:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(
    IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

您的编辑澄清了SPoint 是一个结构。那么这显然是错误的。您可以简单地将SPoint 作为out 参数传递。那将是最简单的解决方案。

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(
    IntPtr hWnd, int Msg, IntPtr wParam, out SPoint lParam);

如果您想要更通用的SendMessage 签名,那么您应该使用我上面所说的IntPtr 并使用Marshal.StructureToPtr。

【讨论】:

  • 对不起,SPoint 是结构体
【解决方案2】:

wParam 参数应该是 IntPtr。但这不是触发 MDA 的原因,对参数类型撒谎是可以的,但你必须正确地做到这一点。结构在 Windows api 中通过引用传递,将 lParam 参数声明为ref SPoint。或者out如果返回结构,则为EM_GETSCROLLPOS。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多