Где python ищет dll, открытую ctypes.cdll. <name>на окнах? - PullRequest
6 голосов
/ 25 июня 2011

Я не могу найти простой ответ на этот вопрос в Интернете, поэтому, возможно, в будущем он будет найден из-за этого вопроса!

Я использую pywiiuse, оболочку для pythonдля библиотеки C wiiuse на windows.Я получил несколько простых примеров на C, которые работают просто включив dll, заголовок и библиотеку в каталог с исходным кодом.

Однако мне интересно, куда поместить dll, чтобы pywiiuse его нашел.Взгляд на источник показывает, что он загружается следующим образом:

dll = ctypes.cdll.wiiuse

Запуск примеров приводит к исключению модуль не найден, когда у меня есть dll в том же каталоге, что и мой тестовый пример.

Где Python ищет DLL?

Ответы [ 2 ]

4 голосов
/ 25 июня 2011

Порядок поиска Windows DLL задокументирован в MSDN. Это не зависит от Python, и нет способа изменить порядок поиска из параметра командной строки. (Но посмотрите в связанной статье другие способы повлиять на порядок поиска.)

Источник до ctypes/__init__.py делает:

from _ctypes import LoadLibrary as _dlopen

Мне не удалось найти определение LoadLibrary в _ctypes.c, но, вероятно, это оболочка для функции Windows LoadLibraryEx, которая ведет себя аналогично функция POSIX dlopen, потому что именно так она используется.

Если вы можете изменить исходный код Python для использования конструктора ctypes.CDLL, он должен работать:

folder = os.path.dirname(os.path.abspath(__file__))
dll_path = os.path.join(folder, "wiiuse.dll")    
dll = ctypes.CDLL(dll_path)

Если это нежизнеспособно, возможно, вы сможете обезопасить ctypes для обработки этого конкретного случая, но это кажется немного опасным. Возможно, просто скопировать библиотеку DLL в ту же папку, что и библиотека Python, было бы самой простой альтернативой.

1 голос
/ 20 июля 2015

Загрузка пользовательской библиотеки DLL в пользовательскую папку с использованием Windows API занимает несколько шагов:

  1. Подтвердите, где они используют вызовы файловой системы - что-то вроде целой кучи строк, похожих на: if path.exists(cwd() + "bin" + "mydll.dll"): return cwd() + "bin". Или, если вы чувствуете себя смелым, просто проложите путь.
  2. Используйте ctypes для загрузки Kernel32.dll - он знает, где он находится.
  3. Загрузить SetDllDirectory из Kernel32.dll. Назовите его по пути, по которому вы знаете, где находятся ваши библиотеки.
  4. Теперь LoadLibrary будет искать Dll в этой папке, поэтому вы можете использовать ctypes для загрузки вашей dll и вызова ваших функций.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...