pyinstaller не может загрузить имеющуюся dll

64-разрядная версия Windows 7 - 32-разрядная версия Python 2.6 - Pymunk 4.0.0

Хорошо, спасибо Использование Pymunk с Pyinstaller. Это заняло у меня много времени, но теперь я понимаю, как закинуть все, что захочу, в exe с помощью Pyinstaller. Однако конкретная библиотека DLL, которая есть, по-прежнему не загружается chipmunk.dll. Вот мой файл .spec для Pyinstaller.

# -*- mode: python -*-
a = Analysis(['Mesh_Animator.py'],
             pathex=['C:\\Users\\username\\workspace\\2D_Mesh_Animator'],
             hiddenimports=[],
             hookspath=None)
import os, pymunk
pymunk_dir = os.path.dirname(pymunk.__file__)
chipmunk_libs = [
    ('chipmunk.dll', os.path.join(pymunk_dir, 'chipmunk.dll'), 'BINARY'),
]
a.datas+=[('imagetest.jpg','imagetest.jpg','DATA')]
a.binaries+=chipmunk_libs
#or just
#a.binaries+=[('chipmunk.dll','chipmunk.dll','BINARY')]
#both seem to work the say way

pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'Mesh_Animator.exe'),
          debug=False,
          strip=None,
          upx=True,
          console=True )

Это все пакеты без проблем. Изображение загружается нормально, пока у меня есть DLL рядом с exe, поэтому я не ошибаюсь. Я подтвердил, что dll была в наличии, сравнив версии до и после включения dll. Разница в 160 кб. Затем я использовал это, чтобы проверить, находится ли dll по текущему пути при запуске в среде Pyinstallers exe.

try:
    print os.listdir(sys._MEIPASS).count("chipmunk.dll"),"dlls"
except:
    #not in pyinstaller
    print 0,"dlls"

На выходе я получаю точное 1 dlls, но пимунк жалуется, что не может его найти. Он находится в директории _MEIPASS PATH, так почему же пимунк не может его найти? DLL находится в корне, поэтому поиск не требуется. Как заставить пимунка искать нужное место?


person Kaliber64    schedule 08.05.2014    source источник
comment
Ваш питон 32-битный или 64-битный? Pymunk в настоящее время поддерживает только 32-битный питон в Windows.   -  person viblo    schedule 09.05.2014


Ответы (2)


Я думаю, это связано с тем, как pymunk пытается найти путь к chipmunk.dll в замороженном состоянии. Видимо требуется специальный код, когда все это упаковывается в один файл. Можете ли вы заменить свой файл libload.py на этот и попробовать еще раз: https://gist.github.com/viblo/44ccd6af88d9f050403b

(На данный момент я не могу попробовать это сам, поэтому суть. Если это сработает, я передам его в реальный репозиторий пимунков)

person viblo    schedule 14.05.2014
comment
хорошо. Я попробую это сейчас. Извини, что так поздно. мой почтовый клиент в последнее время не проверяет мою электронную почту. - person Kaliber64; 22.05.2014
comment
Файл C: \ Users \ kaliber \ workspace \ 2D_Mesh_Animator \ Mesh_Animator.py, строка 892, в обновлении self.Physical_World.step (elapsed) Файл C: \ Python26 \ lib \ site-packages \ pymunk_ init_ .py, строка 374, на шаге cp.cpSpaceStep (self._space, dt) ValueError: процедура вызывается с недостаточным количеством аргументов (отсутствует 12 байт) или неправильным соглашением о вызове - person Kaliber64; 22.05.2014
comment
Так. При запуске pyinstaller он загружал dll во время упаковки. странный. НО! Он загрузил dll, откуда был готов exe. но я все еще получаю указанную выше ошибку. Извините, я не знаю, как исправить эту процедуру. - person Kaliber64; 22.05.2014

Этот фрагмент кода, кажется, устанавливает довольно высокий приоритет на пути, по которому выполняется поиск при загрузке DLL. Вы можете поместить его в самое начало вашей точки входа в вашу программу.

У меня была аналогичная проблема, и у меня она работает :)

try:
    import win32api
    win32api.SetDllDirectory(sys._MEIPASS)
except:
    pass 
person xoolive    schedule 09.09.2015
comment
Большое спасибо. Я попробую это. Единственная проблема, с которой я справился, это то, что мне просто нужно поместить dll рядом с финальным exe-файлом. Что не так уж и важно. но я подумал, что для некоторых проектов я хотел бы иметь возможность распространять только exe. - person Kaliber64; 10.09.2015
comment
Вот как я поступил со своим: сначала определите недостающие библиотеки DLL, поместив их рядом с исполняемым файлом. Затем упаковываем их в a.binaries += (blah, blah, 'BINARY') и добавляем строки выше, чтобы указать каталог, в котором следует искать библиотеки DLL. Затем вы можете выбросить библиотеки DLL рядом с исполняемым файлом. Важное замечание: SetDllDirectory не позволит exe искать библиотеки DLL в текущем каталоге и вместо этого искать в _MEIPASS. Ссылка на интересную ссылку здесь - person xoolive; 10.09.2015