
本文介绍如何使用 Python 的 ctypes 模块准确映射 C 语言中的结构体(如 typedef struct 和指针别名),重点演示 ctypes.Structure 的定义方法及对应指针类型的创建。
本文介绍如何使用 python 的 ctypes 模块准确映射 c 语言中的结构体(如 typedef struct 和指针别名),重点演示 `ctypes.structure` 的定义方法及对应指针类型的创建。
在 Python 中通过 ctypes 调用 C 动态库时,常需将 C 头文件中定义的结构体(尤其是带 typedef 别名的结构)精确还原为 Python 可操作的对象。以如下 C 头文件片段为例:
typedef struct {
void *Handle;
} RESHANDLE, *PRESHANDLE;
该定义声明了一个匿名结构体,并为其赋予两个别名:RESHANDLE(结构体类型本身)和 PRESHANDLE(指向该结构体的指针类型)。
在 ctypes 中,应继承 ctypes.Structure 类,并通过 _fields_ 类变量声明成员名称与类型。注意:_fields_ 必须是元组的列表(即使仅一个字段),每个元素为 (name, type) 形式。void * 在 ctypes 中对应 ctypes.c_void_p。
正确实现如下:
import ctypes as ct
class RESHANDLE(ct.Structure):
_fields_ = [("Handle", ct.c_void_p)]
PRESHANDLE = ct.POINTER(RESHANDLE)
✅ 关键说明:
- _fields_ 是类属性,必须为列表或元组,推荐使用列表以提高可读性(如 [("Handle", ct.c_void_p)]);
- ct.POINTER(RESHANDLE) 返回的是类型对象(非实例),可用于函数参数声明、返回值注解或 ct.cast() 等场景;
- 若结构体后续扩展含其他字段(如 int id; char name[32];),只需按顺序追加到 _fields_ 中,类型分别对应 ct.c_int、ct.c_char * 32。
⚠️ 注意事项:
- 不要将 _fields_ 写成 ('Handle', ct.c_void_p)(单元素元组易漏逗号导致语法错误);
- RESHANDLE 实例默认不自动初始化字段,建议显式赋值(如 obj = RESHANDLE(); obj.Handle = some_ptr);
- 若需兼容 32/64 位平台,c_void_p 已自动适配指针大小,无需手动切换。
掌握此模式后,即可无缝对接各类 C SDK 中的句柄结构、配置结构等,为安全、高效的 Python-C 交互打下坚实基础。











