我在Gdi32.dll中调用CreateRectRgn
。此函数的正常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,即“参数不正确。”
关于可能出现什么问题的任何想法?
答案 0 :(得分:1)
喔。 Microsoft在x64上使用的调用约定是来自STDCALL的totally different。在对CreateRectRgn
的调用中,堆栈根本不用于参数,它们都在寄存器中传递。当我尝试传递RECT
结构时,它会在堆栈上复制结构,并将指向此副本的指针放在寄存器中。因此,这个小技巧在64位Windows中根本不起作用。现在我必须完成我的所有互操作代码并找到我已经完成的其他地方并将它们全部拿出来。