Странная проблема P / Invoke на Win 7 x64 - PullRequest
1 голос
/ 15 февраля 2011

Я P / Invoking для CreateRectRgn в gdi32.dll.Обычная подпись 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 стек должен находиться в идентичном состоянии.И действительно, на Windows XP 32-битная работает без нареканий.Но в Windows 7, 64-битной, функция возвращает ноль, а Marshal.GetLastWin32Error() возвращает 87, что означает «Неверный параметр».

Есть идеи относительно того, в чем может быть проблема?

1 Ответ

1 голос
/ 15 февраля 2011

О.Соглашение о вызовах, которое Microsoft использует в x64, полностью отличается от STDCALL.При вызове CreateRectRgn стек вообще не используется для параметров, все они передаются в регистрах.Когда я пытаюсь передать структуру RECT, она создает копию структуры в стеке и помещает указатель на эту копию в регистр.Поэтому этот маленький трюк не будет работать вообще в 64-битной Windows.Теперь мне нужно пройти через весь код взаимодействия, найти другие места, где я это сделал, и вытащить их все.

...