我的项目将静态库(称为static.lib)公开给CPython (3.8)解释器。它由一个静态库组成,该库依赖于DLL FTDI驱动程序。在阅读这条线之后,提供第三方DLL的最佳解决方案似乎是将它们与package捆绑在一起,以确保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进行虚拟环境管理。
建议的答案这里和这里概述了一个非常相似的setup.py和包含DLL通过package_data选项的相同方法。答案似乎表明DLL和.pyd放在相同的水平上,这对我来说是不可能的。我不知道我错过的是什么,得到了同样的行为。
python 3.8.6
setuptools 51.0.0
pip 20.3.1DLL被放置在与.pyd二进制文件不同的目录中,从而使其在Windows加载程序中不可见
发布于 2021-01-06 05:38:53
经过一番挖掘,我找到了一种适合我的方法。这个帖子揭示了在Windows上加载DLL的问题,以及最近(Python3.8)在这个问题上的发展。
我所使用的解决方案是从numpy借来的。为了正确地将DLL与C扩展捆绑在一起:
sdist和轮询发行版。粗略地说,将package_data添加到您的setup.py应该可以做到这一点(除去清单文件附带的恶作剧和使用package_data,请阅读更多的这里)
package_data={"your package name": ["path_to_DLLs/*"]},要实现#3,作为包的__init__.py中的一个选项,添加以下内容(从numpy __config__.py逐行获取99%,由非常复杂的构建系统自动生成)。
import os
import sys
PATH_TO_DLL = "YOUR DLL DIRECTORY IN YOUR PACKAGE"
extra_dll_dir = os.path.join(os.path.dirname(__file__), PATH_TO_DLL)
if sys.version_info >= (3, 8):
os.add_dll_directory(extra_dll_dir)
else:
# legacy DLL loading mechanism through PATH env variable manipulations
os.environ.setdefault("PATH", "")
os.environ["PATH"] += os.pathsep + extra_dll_dir任何反馈都是非常感谢的。链接到此票证的线程讨论了对C扩展板的更好文档的需求,我没有找到任何文档。到目前为止,C扩展+ Windows + setuptools提供了令人难以置信的令人沮丧的体验。
https://stackoverflow.com/questions/65334494
复制相似问题