GetWindowLong против GetWindowLongPtr в C#

Я использовал GetWindowLong, как это:

[DllImport("user32.dll")]
private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);

Но в соответствии с документами MSDN я должен использовать GetWindowLongPtr для совместимости с 64-битной версией. http://msdn.microsoft.com/en-us/library/ms633584(VS.85).aspx

Документы MSDN для GetWindowLongPtr говорят, что я должен определить это так (в C++):

LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);

Раньше я использовал IntPtr в качестве возвращаемого типа, но какого черта я использовал бы для эквивалента LONG_PTR? Я также видел GetWindowLong, определенный как это в C#:

[DllImport("user32.dll")]
private static extern long GetWindowLong(IntPtr hWnd, int nIndex);

Что правильно, и как я могу обеспечить надлежащую 64-битную совместимость?

3 ответа

Решение

К сожалению, это не так просто, потому что GetWindowLongPtr не существует в 32-битной Windows. В 32-битных системах GetWindowLongPtr - это просто макрос C, который указывает на GetWindowLong. Если вам действительно нужно использовать GetWindowLongPtr как в 32-, так и в 64-битных системах, вам нужно будет выбрать правильный для вызова во время выполнения. Смотрите описание на pinvoke.net

Вы должны определить GetWindowLongPtr, используя IntPtr. В C/C++ LONG_PTR является 32-разрядным в 32-разрядной системе и 64-разрядным в 64-разрядной системе (см. Здесь). IntPtr в C# спроектирован так же (см. Здесь).

Итак, что вы хотите, это:

[DllImport("user32.dll")]
private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);

SoapBox правильно.

Кроме того, если вам когда-нибудь понадобится узнать, как тип или функция должны маршалировать в Win32, попробуйте использовать PInvoke Interop Assistant. Он будет иметь встроенные поколения для большинства Win32 API и может выполнять пользовательскую генерацию на основе фрагментов кода.

Другие вопросы по тегам