2011-02-14 65 views
1

我是P /在gdi32.dll中調用CreateRectRgn。此功能的正常的P/Invoke簽名是:Win 7 x64上的奇怪P /調用問題

[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,即「該參數不正確。」

任何想法可能是什麼問題?

回答

1

哦。 Microsoft在x64上使用的調用約定是來自STDCALL的totally different。在對CreateRectRgn的調用中,堆棧根本不用於參數,它們都被傳入寄存器。當我嘗試通過一個RECT結構時,它會在堆棧上覆制一個結構,並將一個指向這個副本的指針放入一個寄存器中。因此,這個小技巧在64位Windows中完全不起作用。現在我必須通過我所有的互操作代碼,並找到其他地方,我已經完成了這些,並把它們全部拿出來。