Win 7 x64 上奇怪的 P/Invoke 问题
我正在对 gdi32.dll 中的 CreateRectRgn
进行 P/Invoking。此函数的正常 P/Invoke 签名是:
[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(int nLeft, int nTop, int nRight, int nBottom);
作为快捷方式,我还定义了此重载:(
[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(RECT rc);
[StructLayout(LayoutKind.Sequential)]
struct RECT{
public int left;
public int top;
public int right;
public int bottom;
}
是的,我知道 CreateRectRgnIndirect
,但由于我必须使用函数在 >System.Drawing.Rectangle
和这个 RECT
结构,上面对我来说更有用,因为它不涉及中间变量。)
此重载应该与正常签名相同,因为它应该在进入 CreateRectRgn
时将堆栈置于相同的状态。事实上,在 32 位 Windows XP 上,它可以完美运行。但在 Windows 7 64 位上,该函数返回零,并且 Marshal.GetLastWin32Error()
返回 87,即“参数不正确”。
关于可能出现什么问题有什么想法吗?
I'm P/Invoking to CreateRectRgn
in gdi32.dll. The normal P/Invoke signature for this function is:
[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(int nLeft, int nTop, int nRight, int nBottom);
As a shortcut, I've also defined this overload:
[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(RECT rc);
[StructLayout(LayoutKind.Sequential)]
struct RECT{
public int left;
public int top;
public int right;
public int bottom;
}
(Yes, I am aware of CreateRectRgnIndirect
, but since I must use functions to convert between System.Drawing.Rectangle
and this RECT
structure, the above is more useful to me, as it doesn't involve an intermediate variable.)
This overload should work identically to the normal signature, since it should put the stack in an identical state at entry to CreateRectRgn
. And indeed, on Windows XP, 32-bit, it works flawlessly. But on Windows 7, 64-bit, the function returns zero, and Marshal.GetLastWin32Error()
returns 87, which is "The parameter is incorrect."
Any ideas as to what could be the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哦。 Microsoft 在 x64 上使用的调用约定与 STDCALL 完全不同。在对
CreateRectRgn
的调用中,堆栈根本不用于参数,它们都是在寄存器中传递的。当我尝试传递RECT
结构时,它会在堆栈上创建该结构的副本,并将指向该副本的指针放入寄存器中。因此,这个小技巧在64位Windows中根本不起作用。现在我必须检查所有互操作代码并找到我完成此操作的其他位置并将它们全部取出。Oh. The calling convention Microsoft uses on x64 is totally different from STDCALL. In the call to
CreateRectRgn
, the stack isn't used for the parameters at all, they're all passed in registers. When I try to pass aRECT
structure, it makes a copy of the structure on the stack, and puts a pointer to this copy in a register. Therefore, this little trick won't work at all in 64-bit Windows. Now I've got to go through all my interop code and find other places I've done this and take them all out.