"调用一个PInvoke的功能失衡堆栈" [英] "A call to a PInvoke function has unbalanced the stack"

查看:185
本文介绍了"调用一个PInvoke的功能失衡堆栈"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创造了在Visual C#一个窗体应用程序,使用函数生成鼠标点击,但我得到了以下错误消息:

  A调用PInvoke的函数'...... Form1中:: mouse_event'已经失衡堆栈。
这可能是因为管理的PInvoke签名不匹配的非托管目​​标
签名。检查调用约定和的PInvoke签名匹配的参数
目标非托管签名。
 

我的code:

  [的DllImport(user32.dll中,字符集= CharSet.Auto,CallingConvention = CallingConvention.StdCall)
公共静态外部无效mouse_event(dwFlags中长,长DX,DY长,长cButtons,长dwExtraInfo);

私人const int的MOUSEEVENTF_LEFTDOWN = 0×02;
私人const int的MOUSEEVENTF_LEFTUP = 0×04;

...

无效GenerateMouseClick(INT X,int y)对
{
    Cursor.Position =新的点((INT)X,(INT)Y);
    mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP,Cursor.Position.X,Cursor.Position.Y,0,0);
}
 

解决方案

您的Win32 API的声明是不正确:长映射到Int64的.NET Framework中,这几乎总是不正确的Windows API调用

与诠释更换长应该工作:

的公共静态外部无效mouse_event(INT dwFlags中,诠释DX,诠释DY,诠释cButtons,INT dwExtraInfo);

对于未来的参考,你可能要检查时,你正在寻找调用API函数的正确方法pinvoke.net - 虽然它并不完美,它会显示的的正确声明mouse_event

(编辑,2012年3月26):虽然我提供确实的申报工作,将 UINT 就更好了,是Win32的 DWORD 是一个32位的签名的整数。在这种情况下,你会逃脱使用有符号整数,而不是(因为无论是标志,也没有其他参数都不会大到足以引起招牌溢出),但是这绝对不是总是如此。该pinvoke.net声明是正确的,因为是这样的:

 公共静态外部无效mouse_event(UINT dwFlags中,UINT DX,DY UINT,UINT cButtons,UINT dwExtraInfo);
 

另一个回答这个问题,已经提供了这个准确的申报,并在 UINT 问题也指出了意见。我编辑我自己的答案,使这个更加明显;其他SO参与者应该总是随意编辑不正确的帖子,以及,顺便说一句。

I created a Form application in visual c#, that uses a function to generate mouse click, but i got the following error message:

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.

My Code:

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

解决方案

Your Win32 API declaration is incorrect: 'long' maps to Int64 in the .NET Framework, which is almost always incorrect for Windows API calls.

Replacing long with int should work:

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

For future reference, you may want to check pinvoke.net whenever you're looking for the correct way to invoke API functions -- although it's not perfect, it would have shown the correct declaration for mouse_event.

(EDIT, 26 March 2012): And although the declaration I provided indeed works, replacing long with uint would be even better, as Win32's DWORD is a 32-bit unsigned integer. In this case, you'll get away with using a signed integer instead (as neither the flags nor the other arguments will ever be large enough to cause sign overflow), but this is definitely not always the case. The pinvoke.net declaration is correct, as is the following:

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

Another answer to this question already provided this correct declaration, and the uint issue was also pointed out in comments. I edited my own answer to make this more obvious; other SO participants should always feel free to edit incorrect posts as well, BTW.

这篇关于"调用一个PInvoke的功能失衡堆栈"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆