python c函数 库_16.16. ctypes — Python 的外部函数库 — Python 3.6.13 文档

16.16.2.2.加载动态链接库¶

有很多方式可以将动态链接库加载到 Python 进程。其中之一是实例化以下类的其中一个:

classctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)¶

此类的实例即已加载的动态链接库。库中的函数使用标准 C 调用约定,并假定返回 int 。

classctypes.OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)¶

仅 Windows : 此类的实例即加载好的动态链接库,其中的函数使用 stdcall 调用约定,并且假定返回 windows 指定的 HRESULT 返回码。 HRESULT 的值包含的信息说明函数调用成功还是失败,以及额外错误码。 如果返回值表示失败,会自动抛出 OSError 异常。

在 3.3 版更改:以前是引发 WindowsError。

classctypes.WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)¶

仅 Windows: 此类的实例即加载好的动态链接库,其中的函数使用 stdcall 调用约定,并假定默认返回 int 。

在 Windows CE 上,只能使用 stdcall 调用约定,为了方便, WinDLL 和 OleDLL 在这个平台上都使用标准调用约定。

调用动态库导出的函数之前,Python会释放 global interpreter lock ,并在调用后重新获取。

classctypes.PyDLL(name, mode=DEFAULT_MODE, handle=None)¶

这个类实例的行为与 CDLL 类似,只不过 不会 在调用函数的时候释放 GIL 锁,且调用结束后会检查 Python 错误码。 如果错误码被设置,会抛出一个 Python 异常。

所以,它只在直接调用 Python C 接口函数的时候有用。

通过使用至少一个参数(共享库的路径名)调用它们,可以实例化所有这些类。也可以传入一个已加载的动态链接库作为 handler 参数,其他情况会调用系统底层的 dlopen 或 LoadLibrary 函数将库加载到进程,并获取其句柄。

mode 可以指定库加载方式。详情请参见 dlopen(3) 手册页。 在 Windows 上, 会忽略 mode ,在 posix 系统上, 总是会加上 RTLD_NOW ,且无法配置。

use_errno 参数如果设置为 true,可以启用ctypes的机制,通过一种安全的方法获取系统的 errno 错误码。 ctypes 维护了一个线程局部变量,它是系统 errno 的一份拷贝;如果调用了使用 use_errno=True 创建的外部函数, errno 的值会与 ctypes 自己拷贝的那一份进行交换,函数执行完后立即再交换一次。

The function ctypes.get_errno() returns the value of the ctypes private

copy, and the function ctypes.set_errno() changes the ctypes private copy

to a new value and returns the former value.

use_last_error 参数如果设置为 true,可以在 Windows 上启用相同的策略,它是通过 Windows API 函数 GetLastError()  和 SetLastError() 管理的。 ctypes.get_last_error() 和 ctypes.set_last_error() 可用于获取和设置 ctypes 自己维护的 windows 错误码拷贝。

ctypes.RTLD_GLOBAL

用于 mode 参数的标识值。在此标识不可用的系统上,它被定义为整数0。

ctypes.RTLD_LOCAL

Flag to use as mode parameter. On platforms where this is not available, it

is the same as RTLD_GLOBAL.

ctypes.DEFAULT_MODE

加载动态链接库的默认模式。在 OSX 10.3 上,它是 RTLD_GLOBAL ,其余系统上是 RTLD_LOCAL 。

Instances of these classes have no public methods. Functions exported by the

shared library can be accessed as attributes or by index. Please note that

accessing the function through an attribute caches the result and therefore

accessing it repeatedly returns the same object each time. On the other hand,

accessing it through an index returns a new object each time:

>>>libc.time == libc.time

True

>>>libc['time'] == libc['time']

False

还有下面这些属性可用,他们的名称以下划线开头,以避免和导出函数重名:

PyDLL._handle¶

用于访问库的系统句柄。

PyDLL._name¶

传入构造函数的库名称。

共享库也可以通用使用一个预制对象来加载,这种对象是 LibraryLoader 类的实例,具体做法或是通过调用 LoadLibrary() 方法,或是通过将库作为加载实例的属性来提取。

classctypes.LibraryLoader(dlltype)¶

加载共享库的类。 dlltype 应当为 CDLL, PyDLL, WinDLL 或 OleDLL 类型之一。

__getattr__() 具有特殊的行为:它允许通过将一个共享库作为库加载器实例的属性进行访问来加载它。 加载结果将被缓存,因此重复的属性访问每次都会返回相同的库。

LoadLibrary(name)¶

加载一个共享库到进程中并将其返回。 此方法总是返回一个新的库实例。

可用的预制库加载器有如下这些:

ctypes.cdll

创建 CDLL 实例。

ctypes.windll

仅Windows中: 创建 WinDLL 实例.

ctypes.oledll

仅Windows中: 创建 OleDLL 实例。

ctypes.pydll

创建 PyDLL 实例。

要直接访问 C Python api,可以使用一个现成的 Python 共享库对象:

ctypes.pythonapi

一个 PyDLL 的实例,它将 Python C API 函数作为属性公开。 请注意所有这些函数都应返回 C int,当然这也不是绝对的,因此你必须分配正确的 restype 属性以使用这些函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值