Странная проблема P/Invoke на Win 7 x64
Я 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 ответ
Ой. Соглашение о вызовах, которое Microsoft использует на x64, полностью отличается от STDCALL. В призыве к CreateRectRgn
стек вообще не используется для параметров, все они передаются в регистрах. Когда я пытаюсь передать RECT
структура, она делает копию структуры в стеке и помещает указатель на эту копию в регистр. Поэтому этот маленький трюк не будет работать вообще в 64-битной Windows. Теперь мне нужно пройти через весь код взаимодействия, найти другие места, где я это сделал, и вытащить их все.