Функции доступны в качестве атрибутов объектов в DLL :
>>> from ctypes import * # в Linux необходимо загрузить # C-библиотеку следующим образом: # libc = CDLL("libc.so.6") # смотрите раздел "Загрузка C-библиотек" >>> libc.printf # <_FuncPtr object at 0x7f8c52ea4640> # далее только для Windows >>> print(windll.kernel32.GetModuleHandleA) # <_FuncPtr object at 0x...> >>> print(windll.kernel32.MyOwnFunction) # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # File "ctypes.py", line 239, in __getattr__ # func = _StdcallFuncPtr(name, self) # AttributeError: function 'MyOwnFunction' not found
Обратите внимание, что системные dll win32, такие как kernel32
и user32
, часто экспортируют ANSI, а также UNICODE версии функции. Версия UNICODE экспортируется с добавлением символа W
к имени функции, а версия ANSI с добавлением A
к имени. Функция Win32 GetModuleHandle()
, которая возвращает дескриптор модуля для данного имени модуля, имеет прототип C, а макрос используется для предоставления одного из них как GetModuleHandle()
в зависимости от того, определен ли UNICODE или нет:
/* ANSI version */ HMODULE GetModuleHandleA(LPCSTR lpModuleName); /* UNICODE version */ HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
Объект windll
не пытается выбрать один из них волшебным образом, необходимо получить доступ к нужной версии, явно указав GetModuleHandleA()
или GetModuleHandleW()
, а затем вызвать ее с байтовыми или строковыми аргументами соответственно.
Иногда библиотеки DLL экспортируют функции с именами, которые не являются действительными идентификаторами Python, например '??2@YAPAXI@Z'
. В этом случае, для получения функции, используйте функцию Python getattr()
:
>>> getattr(cdll.msvcrt, '??2@YAPAXI@Z') # <_FuncPtr object at 0x...>
В Windows некоторые DLL экспортируют функции не по имени, а по порядковому номеру. Доступ к этим функциям можно получить, указав объект dll по порядковому номеру:
>>> cdll.kernel32[1] # <_FuncPtr object at 0x...> >>> cdll.kernel32[0] # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # File "ctypes.py", line 310, in __getitem__ # func = _StdcallFuncPtr(name, self) # AttributeError: function ordinal 0 not found