python模块dlls

Fir*_*cer 18 python module

有没有一种方法,使一个Python模块加载DLL在我的应用程序目录,而不是与Python安装附带的版本,而无需对Python安装变化(当时这需要我做了一个安装程序,并小心我没"通过覆盖python模块和更改dll版本全球范围来打破其他应用程序的人...)?

具体来说,我想python的使用sqlite3.dll的我的版本,而不是与Python附带的版本(这是旧的并没有出现有FTS3模块).

Gly*_*yph 27

如果您正在谈论Python模块DLL,那么只需修改即可sys.path.但是,如果您正在讨论这些DLL 链接的DLL; 即a 依赖于libfoo.dll哪一个foo.pyd,那么你需要修改你的PATH环境变量.我写了一段时间以前为PyGTK做过这样的事情,但在你的情况下,我认为应该这样简单:

import os
os.environ['PATH'] = 'my-app-dir' + os.pathsep + os.environ['PATH']
Run Code Online (Sandbox Code Playgroud)

这将插入my-app-dirWindows路径的头部,我相信它也控制DLL的加载顺序.

请记住,在加载有问题的DLL之前,您需要执行此操作,即在导入任何有趣的内容之前.

但是,sqlite3可能有点特殊,因为它是用Python分发的; 快速测试这显然有点棘手,所以我没有sqlite3.dll具体检查.


Fir*_*cer 6

好吧,不管python和os路径设置为什么,python总是将pll加载到与pyd文件相同的目录中.

所以我需要将_sqlite3.pyd从python/v2.5/DLLS复制到新的sqlite3.dll所在的app目录,使其加载我的新dll,而不是python附带的那个(因为pyd文件似乎跟随PYTHONPATH,即使actaul dlls自己也不.)


And*_*zov 6

修改的答案os.environ['PATH']是正确的,但它对我不起作用,因为我使用的是 python 3.9。我仍然收到错误:

导入错误:导入模块 X 时 DLL 加载失败:找不到指定的模块。

原来从 python 3.8 版本开始,他们添加了一种机制来更安全地执行此操作。阅读https://docs.python.org/3/library/os.html#os.add_dll_directory 上的文档os.add_dll_directory

具体看python 3.8有什么新东西

扩展模块的 DLL 依赖项和在 Windows 上加载 ctypes 的 DLL 现在可以更安全地解决。仅搜索系统路径、包含 DLL 或 PYD 文件的目录以及使用 add_dll_directory() 添加的目录以查找加载时依赖项。具体来说,不再使用 PATH 和当前工作目录,对它们的修改将不再对正常的 DLL 解析产生任何影响。如果您的应用程序依赖于这些机制,您应该检查 add_dll_directory() 并且如果它存在,在加载您的库时使用它来添加您的 DLL 目录。

所以现在这是使它在python 3.8 及更高版本中工作的新方法:

import os
os.add_dll_directory('my-app-dir')
Run Code Online (Sandbox Code Playgroud)

同样,旧方法仍然正确,您必须在python 3.7 及更早版本中使用它:

import os
os.environ['PATH'] = 'my-app-dir' + os.pathsep + os.environ['PATH']
Run Code Online (Sandbox Code Playgroud)

之后,我的具有 dll 依赖项的模块已成功加载。