pyinstaller 无法加载已存在的 dll

0 投票
2 回答
2600 浏览
提问于 2025-04-18 05:49

这是关于在Windows 7 64位系统上,使用Python 2.6 32位和Pymunk 4.0.0的一个问题。

感谢使用Pyinstaller打包Pymunk的帖子。我花了很长时间,但现在我明白如何用Pyinstaller把我想要的东西打包成exe文件了。不过,有一个特定的dll文件——也就是chipmunk.dll,还是无法加载。

这是我为Pyinstaller准备的.spec文件。

# -*- 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确实被包含在内,大小差了160KB。然后我用这个方法检查在Pyinstaller的exe环境下,dll是否在当前路径中。

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

输出时我得到了确切的1 dlls,但pymunk却抱怨找不到它。这个dll在_MEIPASS的PATH目录里,为什么pymunk找不到呢?dll在根目录,所以不应该需要搜索。那我该怎么让pymunk去正确的位置查找呢?

2 个回答

0

这段代码似乎给加载DLL时搜索的路径设置了一个比较高的优先级。你可以把它放在你程序入口的最前面。

我之前也遇到过类似的问题,这个方法对我有效 :)

try:
    import win32api
    win32api.SetDllDirectory(sys._MEIPASS)
except:
    pass 
0

我觉得这跟pymunk在打包成一个文件时,如何找到chipmunk.dll的路径有关。显然,当所有内容打包成一个文件时,需要一些特殊的代码。你可以试着用这个文件替换你的libload.py文件,然后再试一次:https://gist.github.com/viblo/44ccd6af88d9f050403b

(目前我自己无法尝试,所以才分享这个链接。如果有效的话,我会把它提交到真正的pymunk仓库里)

撰写回答