1

CreateRectRgn在 gdi32.dll 中 P/Invoking to。此函数的正常 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.RectangleRECT

这个重载应该与正常签名一样工作,因为它应该在入口处将堆栈置于相同的状态CreateRectRgn。事实上,在 32 位的 Windows XP 上,它可以完美运行。但在 Windows 7 64 位上,该函数返回 0,并Marshal.GetLastWin32Error()返回 87,即“参数不正确”。

关于可能是什么问题的任何想法?

4

1 回答 1

1

哦。Microsoft 在 x64 上使用的调用约定与 STDCALL完全不同。在对 的调用中CreateRectRgn,堆栈根本不用于参数,它们都在寄存器中传递。当我尝试传递一个RECT结构时,它会在堆栈上制作该结构的副本,并将指向该副本的指针放入寄存器中。因此,这个小技巧在 64 位 Windows 中根本不起作用。现在我必须检查我所有的互操作代码并找到我做过的其他地方并将它们全部取出。

于 2011-02-15T05:14:45.160 回答