Pyinstaller 没有加载 DLL
Pyinstaller not loading DLL
为我的 python 脚本构建 exe dungeon.py
后,当 PyBearLibTerminal.py
(我的程序导入的脚本)尝试加载 DLL BearLibTerminal.dll
.脚本运行正常,只是 运行 导致错误的可执行文件。 运行 可执行文件为
时报告的错误
[3464] Failed to execute script dungeon
Traceback (most recent call last):
File "dungeon.py", line 2, in <module>
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1129, in _exec
File "C:\Program Files\Python34\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 631, in exec_module
exec(bytecode, module.__dict__)
File "PyBearLibTerminal.py", line 50, in <module>
RuntimeError: BearLibTerminal library cannot be loaded.
这是导致错误的 PyBearLibTerminal.py
文件的开头。
import sys, ctypes, numbers, os
_version3 = sys.version_info >= (3, 0)
_library = None
_possible_library_names = [
'BearLibTerminal.dll', # Generic Windows DLL
'./libBearLibTerminal.so', # Local Linux SO
'./libBearLibTerminal.dylib', # Local OS X dylib
'./BearLibTerminal.so', # Local Linux SO w/o prefix
'libBearLibTerminal.so', # System Linux SO
'libBearLibTerminal.dylib', # System OS X dylib
'BearLibTerminal.so' # System Linux SO w/o prefix
]
ctypes.windll.kernel32.SetDllDirectoryW(os.getcwd().replace('\', '/'))
for name in _possible_library_names:
try:
_library = ctypes.CDLL(name)
break
except OSError:
continue
if _library is None:
raise RuntimeError("BearLibTerminal library cannot be loaded.")
最后,这是我的 dungeon.spec
文件:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['dungeon.py'],
pathex=['C:\Users\Brett\Documents\Projects\Spark'],
binaries=[('BearLibTerminal.dll', '.')],
datas=[('enemies.json', '.'), ('items.json', '.'), ('materials.json', '.'), ('names.json', '.'), ('unifont-8.0.01.ttf', '.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='dungeon',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='dungeon')
1) 检查 dist/ 文件夹(或 .exe 所在的任何文件夹)以确保 BearLibTerminal.dll 在那里并准备好被访问。如果不存在,您的 .exe 将不会 运行
2) 接下来检查依赖关系。不一定是找不到BearLibTerminal.dll,而是找不到BearLibTerminal.dll依赖的东西。如果您的计算机上安装了 Visual Studio,请使用 dumpbin 找出您的 DLL 所依赖的内容。 (dumpbin这里安装C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\dumpbin.exe)
dumpbin /DEPENDENTS your.dll
这将列出 BearLibTerminal.dll 依赖的 DLL。如果它们适用,请确保它们包含在与您的 exe 相同的目录中(例如 kernel32.dll 不需要在该目录中)
3) 如果您没有 Visual Studio 或 dumpbin,请下载 http://www.dependencywalker.com/,它会完成同样的事情
4) 如果您确定您的 DLL 和它所依赖的 DLL 都已被考虑在内,请检查您的规范文件以确保其格式正确。如果在 运行ning pyinstaller 时显示一堆警告,那可能会导致问题。特别是如果 Windows 10(他们打得不好:https://github.com/pyinstaller/pyinstaller/issues/1566)
5) 如果 BearLibTerminal.dll 是您自己编译的 dll,请确保它是在发布模式下构建的并且您的 C/C++ 代码生成 运行time 库是 /MT (多线程)
6) 确保你也有最新版本的 pyinstaller。
信息量很大,希望能帮到您解决问题。我自己也在处理同样的问题。
为我的 python 脚本构建 exe dungeon.py
后,当 PyBearLibTerminal.py
(我的程序导入的脚本)尝试加载 DLL BearLibTerminal.dll
.脚本运行正常,只是 运行 导致错误的可执行文件。 运行 可执行文件为
[3464] Failed to execute script dungeon
Traceback (most recent call last):
File "dungeon.py", line 2, in <module>
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1129, in _exec
File "C:\Program Files\Python34\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 631, in exec_module
exec(bytecode, module.__dict__)
File "PyBearLibTerminal.py", line 50, in <module>
RuntimeError: BearLibTerminal library cannot be loaded.
这是导致错误的 PyBearLibTerminal.py
文件的开头。
import sys, ctypes, numbers, os
_version3 = sys.version_info >= (3, 0)
_library = None
_possible_library_names = [
'BearLibTerminal.dll', # Generic Windows DLL
'./libBearLibTerminal.so', # Local Linux SO
'./libBearLibTerminal.dylib', # Local OS X dylib
'./BearLibTerminal.so', # Local Linux SO w/o prefix
'libBearLibTerminal.so', # System Linux SO
'libBearLibTerminal.dylib', # System OS X dylib
'BearLibTerminal.so' # System Linux SO w/o prefix
]
ctypes.windll.kernel32.SetDllDirectoryW(os.getcwd().replace('\', '/'))
for name in _possible_library_names:
try:
_library = ctypes.CDLL(name)
break
except OSError:
continue
if _library is None:
raise RuntimeError("BearLibTerminal library cannot be loaded.")
最后,这是我的 dungeon.spec
文件:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['dungeon.py'],
pathex=['C:\Users\Brett\Documents\Projects\Spark'],
binaries=[('BearLibTerminal.dll', '.')],
datas=[('enemies.json', '.'), ('items.json', '.'), ('materials.json', '.'), ('names.json', '.'), ('unifont-8.0.01.ttf', '.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='dungeon',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='dungeon')
1) 检查 dist/ 文件夹(或 .exe 所在的任何文件夹)以确保 BearLibTerminal.dll 在那里并准备好被访问。如果不存在,您的 .exe 将不会 运行
2) 接下来检查依赖关系。不一定是找不到BearLibTerminal.dll,而是找不到BearLibTerminal.dll依赖的东西。如果您的计算机上安装了 Visual Studio,请使用 dumpbin 找出您的 DLL 所依赖的内容。 (dumpbin这里安装C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\dumpbin.exe)
dumpbin /DEPENDENTS your.dll
这将列出 BearLibTerminal.dll 依赖的 DLL。如果它们适用,请确保它们包含在与您的 exe 相同的目录中(例如 kernel32.dll 不需要在该目录中)
3) 如果您没有 Visual Studio 或 dumpbin,请下载 http://www.dependencywalker.com/,它会完成同样的事情
4) 如果您确定您的 DLL 和它所依赖的 DLL 都已被考虑在内,请检查您的规范文件以确保其格式正确。如果在 运行ning pyinstaller 时显示一堆警告,那可能会导致问题。特别是如果 Windows 10(他们打得不好:https://github.com/pyinstaller/pyinstaller/issues/1566)
5) 如果 BearLibTerminal.dll 是您自己编译的 dll,请确保它是在发布模式下构建的并且您的 C/C++ 代码生成 运行time 库是 /MT (多线程)
6) 确保你也有最新版本的 pyinstaller。
信息量很大,希望能帮到您解决问题。我自己也在处理同样的问题。