【问题标题】:pyinstaller fails to load a dll that is presentpyinstaller 无法加载存在的 dll
【发布时间】:2015-09-09 17:48:40
【问题描述】:

Windows 7 64 位 - Python 2.6 32 位 - Pymunk 4.0.0

好的,感谢Using Pymunk with Pyinstaller。我花了很长时间,但现在我明白了如何使用 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 )

这一切包都没有问题。只要我在exe旁边有dll,图像就可以正常加载,所以我不会出错。我通过比较包含 dll 的前后版本来确认 dll 存在。 160 kb 的差异。然后我用它来检查在 Pyinstallers exe 环境下启动时 dll 是否在当前路径中。

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

我在输出中得到一个准确的1 dlls,但 pymunk 抱怨它找不到它。它在 _MEIPASS PATH 目录中,为什么 pymunk 找不到它?该 dll 位于根目录中,因此不需要搜索。如何让 pymunk 搜索正确的位置?

【问题讨论】:

  • 你的python是32位还是64位? Pymunk 目前在 windows 上只支持 32bit python。

标签: python path pyinstaller pymunk


【解决方案1】:

我认为这与 pymunk 在冻结时如何尝试查找 chipmunk.dll 的路径有关。当全部打包到一个文件中时,显然需要特殊代码。你能用这个替换你的 libload.py 文件然后再试一次吗:https://gist.github.com/viblo/44ccd6af88d9f050403b

(目前我不能自己尝试这个,因此要点。如果它有效,我会将它提交给真正的 pymunk repo)

【讨论】:

  • 好的。我现在试试。对不起,我来晚了。我的收件箱客户端最近无法检查我的电子邮件。
  • 文件“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 个字节)或调用约定错误
  • 所以。在运行 pyinstaller 时,它会在打包时加载 dll。奇怪的。但!它确实加载了 exe 准备好的 dll。但我仍然收到上述错误。抱歉,我不知道如何修复程序。
【解决方案2】:

这段代码似乎对加载 DLL 时搜索的路径设置了相当高的优先级。您可以将它放在程序入口点的开头。

我遇到了类似的问题,它对我有用 :)

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

【讨论】:

  • 非常感谢。我会试试的。我处理过的唯一大问题是 - 我只需将 dll 放在最终的 exe 旁边。这没什么大不了的。但我认为对于一些项目,我希望能够仅分发一个 exe。
  • 这就是我的处理方式:首先通过将丢失的 DLL 放在 exe 旁边来识别它们。然后用a.binaries += (blah, blah, 'BINARY') 打包它们并添加上面的行来设置搜索DLL 的目录。然后,您可以丢弃 exe 旁边的 DLL。需要注意的重要事项:SetDllDirectory 将阻止 exe 在当前目录中搜索 DLL,并改为查找 _MEIPASS。链接到一个有趣的参考here
猜你喜欢
  • 1970-01-01
  • 2018-03-11
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
  • 2012-01-30
相关资源
最近更新 更多