当前位置: 首页 > news >正文

Python 高手编程系列六十六:ctypes

ctypes 是最流行的模块,用于动态或共享库的函数调用,而不需要编写自定义 C 扩展。
原因很明显。它是标准库的一部分,因此它始终可用,并且不需要任何外部依赖。它是一个外部
函数接口(Foreign Function Interface,FFI)库,并提供了一个用于创建兼容 C 数据类型的 API。
加载库
在 ctypes 中有 4 种类型的动态库加载器和两个使用它们的约定。表示动态和共享库的
类是 ctypes.CDLL、ctypes.PyDLL、ctypes.OleDLL 和 ctypes.WinDLL。最后两个
仅在 Windows 上可用,因此我们不在这里讨论它们。CDLL 和 PyDLL 之间的区别如下。
● ctypes.CDLL:此类表示加载共享库。这些库中的函数使用标准调用约定,并假
定返回 int 类型。GIL 在调用期间释放。
● ctypes.PyDLL:此类工作类似于 CDLL,但 GIL 在调用期间不释放。执行后,将
检查 Python 错误标志,如果设置了异常,就会抛出。它只在从 Python/C API 中直
接调用函数时有用。
要加载库,可以使用适当的参数实例化前面的一个类,或者从与特定类关联的子模块
中调用 LoadLibrary()函数。
● 对于 ctypes.CDLL 使用 ctypes.cdll.LoadLibrary()。
● 对于 ctypes.PyDLL 使用 ctypes.pydll.LoadLibrary()。
● 对于 ctypes.WinDLL 使用 ctypes.windll.LoadLibrary()。
● 对于 ctypes.OleDLL 使用 ctypes.oledll.LoadLibrary()。
加载共享库的主要挑战是如何以便携式方式找到它们。不同的系统对共享库使用不同的后
缀(Windows 上是.dll,OS X 上是.dylib,Linux 上是.so),并在不同的地方搜索它们。在
这个领域,Windows 的处理方式不太符合常规,对于库,它没有一个预定义的命名模式。因此,
我们不会讨论在这个系统上使用 ctypes 加载库的细节,主要集中在以一致和类似的方式处理
这个问题的 Linux 和 Mac OS X 上。如果你对 Windows 平台感兴趣,请参考官方 ctypes 文档,
这些文档有关支持该系统的大量的信息(参考 https://docs.python.org/ 3.5/library/ctypes.html)。
两个库加载约定(LoadLibrary()函数和特定的 librarytype 类)要求你使用完
整的库名称。这意味着需要包括所有预定义的库前缀和后缀。例如,要在 Linux 上加载 C
标准库,你需要编写以下内容:

import ctypes
ctypes.cdll.LoadLibrary(‘libc.so.6’)
<CDLL ‘libc.so.6’, handle 7f0603e5f000 at 7f0603d4cbd0>
这里,在 Mac OS X 上,应该这样:
import ctypes
ctypes.cdll.LoadLibrary(‘libc.dylib’)
幸运的是,ctypes.util 子模块提供了一个 find_library()函数,允许使用其名称加
载库而不带任何前缀或后缀,并且可以在任何具有用于命名共享库的预定义方案的系统上
工作,如下所示:
import ctypes
from ctypes.util import find_library
ctypes.cdll.LoadLibrary(find_library(‘c’))
<CDLL ‘/usr/lib/libc.dylib’, handle 7fff69b97c98 at 0x101b73ac8>
ctypes.cdll.LoadLibrary(find_library(‘bz2’))
<CDLL ‘/usr/lib/libbz2.dylib’, handle 10042d170 at 0x101b6ee80>
ctypes.cdll.LoadLibrary(find_library(‘AGL’))
<CDLL ‘/System/Library/Frameworks/AGL.framework/AGL’, handle 101811610 at
0x101b73a58>
使用 ctypes 调用 C 函数
当库成功加载时,通用的模式是将其存储为与库名称相同的模块级变量。函数可以作为对
象属性访问,因此调用它们就像调用从任何其他导入模块导入的 Python 函数一样,如下所示:
import ctypes
from ctypes.util import find_library

libc = ctypes.cdll.LoadLibrary(find_library(‘c’))

libc.printf(b"Hello world!\n")
Hello world!
13
不幸的是,除了整数,字符串和字节之外的所有内置 Python 类型都与 C 数据类型不兼
容,因此必须使用 ctypes 模块提供的相应类进行包装。表 7-1 是来自 ctypes 文档的兼
容数据类型的完整列表。
表 7-1
ctypes 类型
C 类型
Python 类型
c_bool
_Bool
bool (1)
c_char
char
单字符 bytes 对象
ctypes 类型
C 类型
Python 类型
c_wchar
wchar_t
单字符 string
c_byte
char
int
c_ubyte
unsigned char
int
c_short
short
int
c_ushort
unsigned short
int
c_int
int
int
c_uint
unsigned int
int
c_long
Long
int
c_ulong
unsigned long
int
c_longlong
__int64 or long long
int
c_ulonglong
unsigned __int64 or unsigned long long
int
c_size_t
size_t
int
c_ssize_t
ssize_t or Py_ssize_t
int
c_float
float
float
c_double
double
float
c_longdouble
long double
float
c_char_p
char * (NUL terminated)
bytes 对象 或 None
c_wchar_p
wchar_t * (NUL terminated)
string 或 None
c_void_p
void *
int 或 None
如你所见,上表不包含任何将 Python 集合映射成 C 数组的专用类型。为 C 数组创建
类型的推荐方法是简单地使用带有所需基本 ctypes 类型的乘法运算符,如下所示:
import ctypes
IntArray5 = ctypes.c_int * 5
c_int_array = IntArray5(1, 2, 3, 4, 5)
FloatArray2 = ctypes.c_float * 2
c_float_array = FloatArray2(0, 3.14)
c_float_array[1]

http://www.cnnetsun.cn/news/2896038.html

相关文章:

  • NSK MA系列超顺滑精密丝杠指南
  • Fast DDS配置避坑指南:DomainParticipant的QoS设置与Listener监听器实战详解
  • pyasc的Python算子生态——用Python语法糖包裹Ascend C的底层能力,为昇腾NPU开发者打开自定义算子的Python大门
  • 解锁创意自由:Adobe-GenP 3.0如何为设计师提供一站式解决方案
  • 大模型的应用前景如何?
  • GCP Workspace 用户批量管理与 Gemini License 分配实战指南
  • 告别‘一维’思维:用TimesNet的2D卷积搞定时间序列预测、分类与异常检测
  • 别再死记公式了!用Python动手复现超螺旋滑模观测器(附完整代码)
  • 开源 | 慧知开源OCPP1.6J欧标充电桩管理平台 V2.0.1
  • MC68334嵌入式系统:模块化架构与低功耗设计实战解析
  • 终极E-Hentai下载器完整教程:免费漫画批量下载解决方案
  • ComfyUI-Manager 插件管理指南:从入门到精通的5个关键步骤
  • Flex词法分析器进阶:手把手教你为自定义‘PL语言’添加注释支持和错误恢复
  • Prometheus数据模型详解:时序指标与标签核心原理通俗教程
  • 3-2-1-1备份原则通俗详解:企业数据安全备份标准落地教程
  • FSA95601数字功放控制器:原理、设计与车载音频实战
  • 飞思卡尔68HC08EYxx系列MCU:汽车LIN总线从节点的低成本高集成度解决方案
  • i茅台自动预约系统终极指南:如何实现智能茅台预约管理
  • 基于MPC8275与PM4351的E1接口子卡设计:从硬件到驱动的完整实现
  • 纯Java实现的PGM灰度图查看与手动编辑工具,开箱即用
  • 若依框架下Spring Security多用户表登录的两种姿势:从“框架原生”到“手动接管”的完整对比与选型指南
  • 基于知识库的航空故障推理:从传统RAG到Agent-native架构的演进实战
  • TAP-Windows V9驱动源码工程包(含VS2019+WDK10完整编译支持)
  • 【分享】16.3 写给35+的人:你不是被嫌弃了,你是被错误定价了
  • M4-SAM:多模态MoE+记忆增强SAM,RGB-D视频显著性检测SOTA
  • 南京链家二手房数据自动采集+区域房价可视化分析工具包
  • QProcess进程启动与waitForFinished超时陷阱:实战场景与解决方案
  • RV1109/RV1126 QT应用从开发到部署:两种编译路径的实战解析与避坑指南
  • Visual C++ Redistributable AIO:一键解决Windows程序运行问题的终极方案
  • RT-DETR onnx模型导出踩坑记:opset版本选17还是16?LayerNormalization导出差异详解