无法加载使用 setuptools 打包的 dll

Can't load dll packaged with setuptools

我正在 windows,使用带有 python 3 和 setuptools 的 anaconda。

我在将 DLL 加载到我的包中时遇到问题。我尝试遵循“Packaging resources with setuptools/distribute' as well as 'Python copy a DLL to site-packages on Windows”中的建议,但我似乎遗漏了一些东西。

所以,我的包裹看起来像:

setup.py
package
|--- __init__.py
|--- main.py
|--- subpackage
     |--__init__.py
     |--foo.py
     |--bar.DLL

里面foo.py我做:

import ctypes

my_dll = ctypes.cdll.LoadLibrary('bar.dll')

当我在控制台中 运行 我的脚本时,这有效。但是,一旦我将所有内容打包并安装(例如通过 setuptools 和 pip),我似乎无法加载 dll。

setup.py里面我设置了package_data={'':['*.dll', '*.h', '*.lib']}。安装后,我可以看到所有文件都正确放置在安装位置。一旦我尝试导入我的包,我得到错误:

File "path\to\subpackage\foo.py", line 3, in <module>
    my_dll = ctypes.cdll.LoadLibrary('bar.dll')
  [...]
OSError: [WinError 126] Das angegebene Modul wurde nicht gefunden
(Could not find the given module)

所以,我很确定,我需要首先在 运行 时间更改我的 dll 文件的加载,但我不知道如何。

我正在寻找一个解决方案,它仍然允许我在编辑器中 运行 单个文件 foo.py,但允许我在安装后使用包内的相同文件。

更新 为清楚起见进行了编辑。

更新 16.12.2019 我又发现了一件事:

我尝试了 Sergey 的以下回答

import os
this_dir = os.path.abspath(os.path.dirname(__file__))

my_dll = ctypes.cdll.LoadLibrary(os.path.join(this_dir, 'bar.dll'))

这仅在我当前的工作目录等于 ...\package\subpackage 时有效,因此我假设 LoadLibrary 甚至不尝试搜索给定路径,而只取文件名。

您的 DLL 不在 PATH 中,因此无法找到。

foo.py 中使用 importlib.util 检索其位置:

import os
import importlib.util

spec = importlib.util.find_spec('subpackage', 'package')

my_dll = ctypes.cdll.LoadLibrary(os.path.join(spec.submodule_search_locations, 'bar.dll'))

我没有针对您的特定设置测试此代码,但您应该有一个总体思路

有关 find_spec 的更多信息在 documentation


更简单的方法:

import os
this_dir = os.path.abspath(os.path.dirname(__file__))

my_dll = ctypes.cdll.LoadLibrary(os.path.join(this_dir, 'bar.dll'))