从Python 3.7.6转到Python 3.10.3后找不到DLL
我正在尝试将库升级到 Python 3.10。到目前为止,我一直使用3.7.6。
在我的库中,我使用 DLL。在包 __init__.py
中,我将 DLL 路径添加到 PATH 变量中。因为我想让代码与 32 和 64 位系统兼容,所以我在运行时检查位数并将适当的 DLL 文件夹添加到 PATH:
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 即可。
I am trying to upgrade a library to Python 3.10. Up to now, I have been using 3.7.6.
In my library, I am using DLLs. In the package __init__.py
, I add the DLL path to the PATH variable. Since I want to have the code compatible with 32 and 64 bit systems, I check the bitness at runtime and add the appropriate DLL folder to the PATH:
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
The corrresponding folder structure is
package_root
|- libs
|- x64
|- libbristolpolled.dll
...
|- x86
|- libbristolpolled.dll
...
Then in a sub-package, I am using:
from ctypes import CDLL
dll = "libbristolpolled.dll"
_lib_bristlp = CDLL(dll)
This has worked fine in 3.7.6 but fails in 3.10.3 with the following error message:
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.
If I instead use the absolute path, as the error message suggests, it works:
from ctypes import CDLL
dll = r"C:\...\libs\x64\libbristolpolled.dll"
_lib_bristlp = CDLL(dll)
What is the reason the old method doesn't work anymore, or how can I make it work again? I'd prefer not to have absolute paths in my code and I liked the fact that I handle the DLL path once in the init file and afterwards I just need to import the DLL using the file name.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此特定功能(通过将查找
.dll
的路径添加到PATH
环境变量)已在 Python 3.8 中删除。根据通知,新函数os.add_dll_directory
;引用文档说明更改的原因:
未来更可移植的解决方案是尝试使用该函数,或者只生成绝对路径,就像您当前使用 os.path.dirname 和 os.path.join 所做的那样> 在
dll
变量上 - 即保持与之前的 Python 版本的兼容性;另外,这还假设这些.dll
文件没有外部依赖项,如果有的话,此线程 有关当前问题的更多详细信息(即使使用绝对路径 - 尽管考虑到它确实适用于您的程序和库,但这对于您的用例来说不应该是问题) 。This particular features (by adding the path to find a
.dll
toPATH
environment variable) has been removed in Python 3.8. As per the notice, the new functionos.add_dll_directory
is provided; quoting the documentation for the reason for the change:The more portable solution going forward is to attempt to use that function, alternatively just generate the absolute path as you have current done using
os.path.dirname
andos.path.join
on thedll
variable - i.e. to maintain compatibility with prior Python versions; also this assumes those.dll
files do not have external dependencies, if there are, this thread has a significantly more detail regarding the issues at hand (even with absolute paths - though given that it did appear to work for your program and library, this should not an issue for your use case).