Требует ли P / Invoke в 64-битных окнах подписей, отличных от 32-битных? - PullRequest
7 голосов
/ 15 сентября 2009

Когда я создаю подпись, которая, например, ссылается на user32.dll, я должен создать ее с помощью user64.dll, если целью является 64-битный компьютер?

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(
    IntPtr hWndRemove,
    IntPtr hWndNewNext);

В настоящее время это не проблема, поскольку я нацеливаюсь только на 32-разрядную версию из-за библиотеки поставщика (Progress OpenEdge), которая предоставляет только 32-разрядные библиотеки для доступа к своей базе данных.

В настоящее время у меня нет компьютера с 64-разрядной операционной системой Windows, чтобы проверить, так ли это.

Ответы [ 2 ]

12 голосов
/ 15 сентября 2009

Несмотря на соглашение об именах, user32.dll (и другие 32 ... dll) фактически 64-битные на 64-битных машинах. Это исторические имена для dll, и они были сохранены таким образом, независимо от изменений в базовой архитектуре. Прочитайте эту страницу, чтобы получить более подробную информацию.

5 голосов
/ 15 сентября 2009

Вам следует , а не , необходимо изменить подпись / имя библиотеки DLL, на которую вы ссылаетесь при вызове функций USER32.DLL.

Несмотря на соглашение об именах, на 64-битной машине Windows файл USER32.DLL, который находится в [Windows] \ System32, на самом деле является 64-битной DLL. реальная 32-битная версия USER32.DLL фактически находится в папке [Windows] \ SysWow64.

Пожалуйста, см. этот вопрос для дальнейшей информации.

Единственное, к чему вам, вероятно, следует быть особенно внимательным, это типы данных, которые вы передаете в качестве параметров различным функциям Windows API. Например, функция «SendMessage» в USER32.DLL имеет специальное требование, по крайней мере, с одним из ее параметров (согласно странице в P / Invoke ).

Это подпись:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

и примечания 2 и 3 ниже четко указывают:

2) НИКОГДА не используйте "int" или "integer" в качестве LPARAM. Ваш код вылетит на 64-битной окна. ТОЛЬКО используйте IntPtr, "ref" структура, или структура "вне".

3) НИКОГДА не используйте "bool", "int" или "целое число" в качестве возвращаемого значения. Ваш ядро вылетит на 64-битных окнах. ТОЛЬКО используйте IntPtr. Это не безопасно использовать bool - pInvoke не может вывести IntPtr для логического значения.

Это "предостережение", по-видимому, специфично для этой конкретной функции (SendMessage), хотя я бы обратил особое внимание на это при вызове любых функций Windows API.

...