【发布时间】:2020-12-17 03:52:30
【问题描述】:
我的项目向 CPython (3.8) 解释器公开了一个静态库(称为 static.lib)。它由一个静态库组成,该库又依赖于一个 DLL FTDI 驱动程序。在阅读this thread 之后,似乎提供第三方 DLL 的最佳解决方案是将它们与 Python 包捆绑在一起 - 以确保 DLL 与.pyd 二进制文件位于同一目录中。
我遇到的问题是,在为我的包运行 pip install . 后,所需的 DLL(称为 required.dll)被放置在 site-packages/package/required.dll 中,而实际的 C 扩展库(称为 package.pyd)被放置在site-packages/package.pyd。
因为当我尝试在 Python 中使用库时它不在同一个目录中,所以我得到了
ImportError: DLL load failed while importing package: The specified module could not be found.
下面是我的setup.py
setuptools.setup(
name="package",
version="1.0.0",
packages=setuptools.find_packages(where="src"),
package_dir={"": "src"},
py_modules=[splitext(basename(path))[0] for path in glob("src/*.py")],
use_scm_version=True,
package_data={
"package": [
"_clibs/libs/required.dll",
],
},
ext_modules=[
setuptools.Extension(
"package",
include_dirs=["src/package/_clibs/inc"],
sources=[
"src/package/_clibs/src/api.cpp",
"src/package/_clibs/src/utils.cpp",
],
library_dirs=[
"src/package/_clibs/libs",
],
libraries=["static", "User32"],
language="c++"
),
],
)
项目的目录布局如下:
/
setup.py
.tox
src/
...package/
......wrapper.py
......__init__.py
......_clibs/
.........inc/
.........src/
............api.cpp
............utils.cpp
.........libs/
............required.dll
............static.lib
我还使用tox 进行虚拟环境管理。
建议的答案 here 和 here 概述了一个非常相似的 setup.py 以及包含 DLL 的相同方法 - 通过 package_data 选项。答案似乎表明 DLL 和 .pyd 然后被放置在同一级别,这对我来说不会发生。我无法完全确定获得相同行为所缺少的内容。
python 3.8.6
setuptools 51.0.0
pip 20.3.1
TL;DR DLL 被放置在与.pyd 二进制文件不同的目录中,从而使其对 Windows 加载程序不可见
【问题讨论】:
-
这些是很好的答案,但是我仍然遇到了原始帖子中描述的问题。我尝试将
required.dll放在不同的目录中 - 结果相同。我将编辑答案以包括我的包目录布局。 -
PIP 是如何知道如何构建 library.pyd 的?我在 setup.py 中没有看到它的引用。
-
@CristiFati
library.pyd是setup.py的乘积,将library.pyd替换为最终分配给二进制文件的任何名称。为了与我提供的脚本保持一致,它应该是package.pyd或其一些变体。为混淆道歉,我试图隐藏与这个问题无关的实际库名称,这只是一个不一致
标签: python python-3.x windows dll python-c-api