Python ctypes:从相对路径加载DLL

Fre*_*ool 24 python ctypes

我有一个wrapper.py包含C DLL 的Python模块.DLL与模块位于同一文件夹中.因此,我使用以下代码加载它:

myDll = ctypes.CDLL("MyCDLL.dll")
Run Code Online (Sandbox Code Playgroud)

如果我wrapper.py从自己的文件夹执行,这是有效的.但是,如果我从其他地方运行它,它就会失败.那是因为ctypes计算相对于当前工作目录的路径.

我的问题是,有没有一种方法可以指定相对于包装器而不是当前工作目录的DLL路径?这将使我能够将两者组合在一起,并允许用户从任何地方运行/导入包装器.

Mat*_*hen 25

您可以使用os.path.dirname(__file__)获取Python源文件所在的目录.

  • 像这样的相对路径工作得很好,不需要 `os.path.abspath()` 或将此路径添加到 `$PATH` (`%PATH%`)。一个警告,如果您的 dll 需要另一个 dll,那么您也必须加载它,在加载这个之前,请参阅我在 OP 问题下的评论。 (2认同)

fma*_*ark 13

扩展马修的答案:

import os.path
dll_name = "MyCDLL.dll"
dllabspath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dll_name
myDll = ctypes.CDLL(dllabspath)
Run Code Online (Sandbox Code Playgroud)

这只能用于脚本,而不是控制台,也不能用于py2exe.

  • [`os.path.join`](http://docs.python.org/2/library/os.path.html#os.path.join)在手指和眼睛上更容易.EG:`os.path.abspath(os.path.join(os.path.dirname(__ file __),dll_name))` (7认同)

Chr*_* B. 9

我总是将我的DLL所在的目录添加到路径中.这样可行:

os.environ['PATH'] = os.path.dirname(__file__) + ';' + os.environ['PATH']
windll.LoadLibrary('mydll.dll')
Run Code Online (Sandbox Code Playgroud)

请注意,如果您使用py2exe,这不起作用(因为__file__未设置).在这种情况下,您需要依赖该sys.executable属性(http://www.py2exe.org/index.cgi/WhereAmI上的完整说明)

  • @MarkMikofski太傻了.编辑环境变量的任何应用程序都是唯一可以看到更改的应用程序.他们不坚持.如果他们这样做,那将是一场安全噩梦.无论如何,setup.py都无法更改正在运行的应用程序的环境变量.根据您的内心编辑您的环境. (2认同)
  • 请注意,将 DLL 目录添加到 PATH 环境变量在 Python 3.8+ 中不再起作用。您需要调用新的 `os.add_dll_directory(<path>)` (您可能想有条件地调用它 - `hasattr(os, "add_dll_directory"): ...` - 并修改 Python 3.7 及以下版本的 PATH . 另请参阅 https://docs.python.org/3.8/whatsnew/3.8.html#changes-in-the-python-api (2认同)