Python进阶之-ctypes详解

2024-05-28 09:20
文章标签 python 进阶 详解 ctypes

本文主要是介绍Python进阶之-ctypes详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

✨前言:

什么是ctypes?
ctypes 是 Python 的一个标准库,它提供了和 C 语言库进行交互的能力,允许在 Python 代码中调用 C 库中的函数,并操作 C 语言数据类型。使用 ctypes 可以创建、访问和修改 C 数据类型,并且可以加载动态链接库(DLLs,在 Windows 上)或共享库(.so 文件,在 Unix/Linux 上),调用其中定义的函数。

✨基本数据类型

在 ctypes 中,为了和 C 语言的数据类型相匹配,提供了以下一些基本的数据类型:

c_bool:布尔类型
c_char:字符类型
c_wchar:宽字符类型
c_byte:字节类型
c_ubyte:无符号字节类型
c_short:短整型
c_ushort:无符号短整型
c_int:整型
c_uint:无符号整型
c_long:长整型
c_ulong:无符号长整型
c_longlong:长长整型
c_ulonglong:无符号长长整型
c_float:单精度浮点型
c_double:双精度浮点型
c_longdouble:长双精度浮点型
c_char_p:字符指针类型(用于字符串)
c_wchar_p:宽字符指针类型(用于宽字符串)
c_void_p:void 指针类型

✨内存操作函数

ctypes 提供了一些内存操作的函数,用来创建和操作内存中的 C 数据结构:
byref(obj): 获取对象的内存地址。
pointer(obj): 创建指向对象的指针。
sizeof(obj): 获取对象或类型的大小。
addressof(obj): 获取对象的内存地址。
string_at(addr [, size]): 从指定的内存地址读取字符串。
wstring_at(addr [, size]): 从指定的内存地址读取宽字符串。

✨函数调用

使用 ctypes 调用 C 函数时,你首先需要加载相应的库,然后设置函数的原型(参数类型和返回类型),最后就可以调用函数了。下面是一个调用 C 库函数的例子:

from ctypes import *# 加载动态链接库
lib = cdll.LoadLibrary('libc.so.6')# 获取库中函数的引用
puts = lib.puts# 设置函数参数类型和返回类型
puts.argtypes = [c_char_p]
puts.restype = c_int# 调用函数
puts(b'Hello, world!')

此例中,我们加载了 C 标准库 libc,并从中获取了 puts 函数的引用。我们设置了函数的参数类型为 c_char_p(字符指针),因为 puts 函数接收一个字符串指针作为参数,设置返回类型为 c_int。

✨举例

下面是一个使用 ctypes 调用 C 标准数学库中函数 cos 的例子:

from ctypes import *# 加载数学库
math_lib = cdll.LoadLibrary('libm.so.6')# 获取库中 `cos` 函数的引用
cos_func = math_lib.cos# 设置函数参数类型和返回类型
cos_func.argtypes = [c_double]
cos_func.restype = c_double# 调用 `cos` 函数
result = cos_func(3.14159265 / 3)  # 计算 cos(pi/3)
print(result)  # 输出结果

✨创建和操作结构体(Struct)

C 语言中的结构体在 ctypes 中可以用类来表示。下面是如何定义和使用 C 结构体的例子。

首先是 C 语言中的结构体定义

struct Point {int x;int y;
};

在 Python 中使用 ctypes 表示上述结构体:

from ctypes import *class Point(Structure):_fields_ = [("x", c_int),("y", c_int)]# 使用结构体
point = Point(10, 20)
print(point.x, point.y)  # 输出:10 20# 用 byref 传递结构体引用
some_c_function(byref(point))

✨创建数组类型

使用 ctypes 可以创建 C 数组类型。下面是定义和使用 C 整型数组的例子。

C 语言中数组定义:

int arr[5];

在 Python 中使用 ctypes 表示上述数组:

from ctypes import *IntArray5 = c_int * 5  # 创建一个包含5个整数的数组类型
arr = IntArray5(1, 2, 3, 4, 5)  # 初始化数组
for i in arr:print(i)  # 输出数组元素

✨正确处理字符串

处理字符串时,可以使用 create_string_buffer 来创建 char 数组。

例如,当你需要一个可修改的字符串缓冲区作为函数参数时:

from ctypes import *# 创建字符串缓冲区
buffer = create_string_buffer(50)  # 创建一个容量为50的字符数组# 用某个函数填充缓冲区
# some_c_function_that_fills_buffer(buffer, len(buffer))# 获取缓冲区的内容
print(buffer.value)

✨使用回调函数

在 ctypes 中还可以定义 Python 函数作为 C 语言的回调函数。例如,使用 CFUNCTYPE 创建一个回调函数类型。

from ctypes import *# 定义回调函数类型,这里是 int (*)(int)
CMPFUNC = CFUNCTYPE(c_int, c_int)# Python 中定义的回调函数
def py_cmp_func(a):print("py_cmp_func called with", a)return -a# 使用 CFUNCTYPE 创建 C 可调用的函数指针
cmp_func = CMPFUNC(py_cmp_func)# 假设有一个 C 函数需要回调函数作为参数
# some_c_function_that_takes_callback(cmp_func)# 该 C 函数在某个时刻会调用传进去的回调函数

⚠️注意事项
使用 ctypes 需要你对 C 语言的数据类型和内存模型有一定的了解。
需要确保设置正确的参数和返回值类型,否则可能会导致程序崩溃或者未定义的行为。
调用系统库时要确保兼容性和正确性,不同的操作

这篇关于Python进阶之-ctypes详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010165

相关文章

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os