python - ctypes.CDLL() 和 ctypes.cdll.LoadLibrary() 有什么区别?
问题描述
这两种方法似乎都有效(对我来说),但似乎该CDLL()
方法返回一个具有_handle
属性的对象,该属性可用于通过ctypes.windll.kernel32.FreeLibrary()
(至少在 Windows 上)卸载库 - 我还不知道如何在 Linux 上做到这一点)。
这两种方法有什么区别 - 为什么我会选择另一种?
最终,我的目标是能够在 Linux 上的两个 Windows 上加载和卸载库(因为我有一个第 3 方库,有时似乎会进入损坏状态 - 我希望卸载/重新加载会重置它)。
解决方案
[Python.Docs]中很好地解释了一切: ctypes - Python 的外部函数库:
类ctypes。CDLL ( name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0 )
此类的实例表示已加载的共享库。这些库中的函数使用标准 C 调用约定,并假定返回int。...
类ctypes。库加载器(dlltype)
...
LoadLibrary ( name )
将共享库加载到进程中并返回。此方法始终返回库的新实例。这些预制库加载器可用:
类型。cdll
创建CDLL实例。
所以,第二种形式只是一个方便的包装,它们之间绝对没有功能上的区别,如下所示:
>>> import ctypes as ct >>> >>> >>> k32_1 = ct.CDLL("kernel32.dll") # 1. >>> k32_2 = ct.cdll.LoadLibrary("kernel32.dll") # 2.1. >>> k32_3 = ct.cdll.kernel32 # 2.2. >>> >>> k32_1, k32_2, k32_3 (<CDLL 'kernel32.dll', handle 7fff59100000 at 0x2335c444ee0>, <CDLL 'kernel32.dll', handle 7fff59100000 at 0x2335b44bc10>, <CDLL 'kernel32', handle 7fff59100000 at 0x2335c45a790>) >>> type(k32_1), type(k32_2), type(k32_3) (<class 'ctypes.CDLL'>, <class 'ctypes.CDLL'>, <class 'ctypes.CDLL'>) >>> >>> k32_1._handle == k32_2._handle == k32_3._handle True
使用最适合你的东西。第二种形式(#2.2.
)更短(我想这是它的目的)。#1。和#2.1。是相同的(#2.1.可能更具解释性(因为它具有LoadLibrary))并且它们允许您从自定义路径加载库,或者扩展名不同于默认路径。就个人而言,#1。是我喜欢的那个。
有关更多详细信息,您可以查看[GitHub]:python/cpython - (master) cpython/Lib/ctypes/__init__.py,尤其是实现时的LibraryLoader ,它(cdll实际上是,并且)很容易理解。
只是提醒一下(可能您已经知道要进入什么内容了):加载和卸载库有时会很棘手。
推荐阅读
- angular - 对于 Angular 中的延迟加载模块,是否有类似 APP_INITIALIZER 的东西?
- javascript - Typewriter.typeString (添加一个不会删除的字符串?)
- java - 部署为战争时出现Spring Boot soap ws错误
- postgresql - 在 GROUP BY 中似乎使用列名而不是别名
- javascript - 根据键值从 v-for 返回单个结果
- r - R:仅在我的 Mac 中显示半透明
- node.js - 上传图片错误 - 有效载荷太大
- laravel - 试图获取非对象的属性“post_titile”
- python - 无法安装 Python 机密包
- python - 带有复选框位置的 kivy listitem 按钮