23

有没有办法让 python 模块在我的应用程序目录中加载一个 dll,而不是 python 安装附带的版本,而不更改 python 安装(这需要我制作一个安装程序,小心我没有' t 通过覆盖 python 模块和全局更改 dll 版本来破坏其他应用程序......)?

具体来说,我希望 python 使用我的 sqlite3.dll 版本,而不是 python 附带的版本(它较旧并且似乎没有 fts3 模块)。

4

5 回答 5

32

如果您在谈论 Python 模块 DLL,那么只需修改sys.path就可以了。但是,如果您谈论的是与这些 DLL链接的 DLL;即alibfoo.dllfoo.pyd依赖的a,那么你需要修改你的PATH环境变量。我不久前写过关于为 PyGTK 做这个的文章,但在你的情况下,我认为它应该很简单:

import os
os.environ['PATH'] = 'my-app-dir' + os.pathsep + os.environ['PATH']

这将插入my-app-dir到您的 Windows 路径的开头,我相信它也控制着 DLL 的加载顺序。

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

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

于 2008-10-18T10:33:08.000 回答
9

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

ImportError: DLL load failed while importing module X: 找不到指定的模块。

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

具体见python 3.8 what's new

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

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

import os
os.add_dll_directory('my-app-dir')

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

import os
os.environ['PATH'] = 'my-app-dir' + os.pathsep + os.environ['PATH']

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

于 2020-10-11T12:11:22.953 回答
7

好的,事实证明python总是将dll加载到与pyd文件相同的目录中,而不管python和os路径设置为什么。

所以我需要将 _sqlite3.pyd 从 python/v2.5/DLLS 复制到我的新 sqlite3.dll 所在的应用程序目录中,使其加载我的新 dll,而不是 python 附带的那个(因为 pyd 文件似乎遵循 PYTHONPATH,即使实际的 dll 本身没有)。

于 2008-10-18T11:04:43.690 回答
0

如果您的 sqlite 版本在系统版本之前的 sys.path 中,它将使用它。因此,您可以将其放在当前目录中,也可以更改PYTHONPATH环境变量来执行此操作。

于 2008-10-18T10:20:18.850 回答
0

我遇到了同样的问题,因为默认 python 库的管理权限在公司环境中被阻止,并且执行安装非常麻烦。

什么对我有用:

  1. 在新位置复制 sqlite3 库
  2. 将最新的 sqlite3.dll(您想要的 sqlite3 web 版本)和旧的 _sqlite3.pyd 放入新位置或新的 sqlite3 库。旧的 _sqlite3.pyd 可以在默认的 python 库 lib/DLLs 文件夹中找到。
  3. 转到新的 sqlite3 库并修改 dbapi2.py 如下:将“from _sqlite3 import *”更改为“from sqlite3._sqlite3 import *”
  4. 确保 python 首先加载这个新的 sqlite3 库。如果必须,请添加此库的路径。
于 2021-07-22T11:19:55.367 回答