我正在尝试将库升级到Python 3.10。到目前为止,我已经使用了3.7.6。
在我的图书馆里,我正在使用DLL。在包__init__.py
中,我将DLL路径添加到path变量。由于我希望代码与32位和64位系统兼容,所以我在运行时检查bitness并将适当的DLL文件夹添加到路径中:
import os
import sys
# Add libs to PATH environment variable such that DLLs can be loaded.
# Load either x64 or x86 depending on whether we are running a 32/64
# bit system.
package_directory = os.path.dirname(os.path.abspath(__file__))
if sys.maxsize > 2**32:
path_dir = os.path.join(package_directory, 'libs', 'x64')
else:
path_dir = os.path.join(package_directory, 'libs', 'x86')
os.environ['PATH'] += os.pathsep + path_dir
对应的文件夹结构是
package_root
|- libs
|- x64
|- libbristolpolled.dll
...
|- x86
|- libbristolpolled.dll
...
然后在一个子包中,我使用:
from ctypes import CDLL
dll = "libbristolpolled.dll"
_lib_bristlp = CDLL(dll)
这在3.7.6中运行良好,但在3.10.3中失败,错误消息如下:
File "C:\...\lib\site-packages\optoMD\sensor\optical\bristol\dll_api.py", line 37, in <module>
_lib_bristlp = CDLL(dll) # The correct DLL
File "C:\Program Files\Python310\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'libbristolpolled.dll' (or one of its dependencies). Try using the full path with constructor syntax.
如果我使用绝对路径,正如错误消息所暗示的那样,它可以工作:
from ctypes import CDLL
dll = r"C:\...\libs\x64\libbristolpolled.dll"
_lib_bristlp = CDLL(dll)
旧方法不再起作用的原因是什么,或者我怎样才能让它再次发挥作用?我希望代码中没有绝对路径,我喜欢在init文件中处理一次DLL路径,然后只需要使用文件名导入DLL。
发布于 2022-03-28 10:29:01
这个特殊特性(通过添加路径以找到.dll
到PATH
环境变量) 已在Python3.8中删除。根据通知,提供了新函数os.add_dll_directory
;引用文档说明更改的原因:
版本3.8中的新版本:以前版本的CPython将使用当前进程的默认行为解析DLL。这导致了不一致,例如有时只搜索
PATH
或当前工作目录,而OS函数(如AddDllDirectory
)则没有任何效果。
更可移植的解决方案是尝试使用该函数,或者像当前使用os.path.dirname
和os.path.join
在dll
变量上所做的那样,生成绝对路径--即保持与以前的dll
版本的兼容性;这也假设这些.dll
文件不具有外部依赖关系,如果存在的话,则这条线有更多关于当前问题的详细信息(即使是绝对路径--尽管它看起来确实适用于您的程序和库,这对于您的用例来说不应该是一个问题)。
https://stackoverflow.com/questions/71645822
复制相似问题