【问题标题】:Weird P/Invoke issue on Win 7 x64Win 7 x64 上奇怪的 P/Invoke 问题
【发布时间】:2011-02-14 23:25:57
【问题描述】:

我正在 P/调用 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 位上,函数返回 0,Marshal.GetLastWin32Error() 返回 87,即“参数不正确”。

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

【问题讨论】:

    标签: windows-7 pinvoke win64


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      相关资源
      最近更新 更多