如何通过指针地址初始化ctypes.Structure结构体实例
解决方案
ctypes.Structure 子类原生就支持from_address()类方法,和你之前处理数组的用法完全一致,直接调用即可完成从指针地址初始化结构体实例:
# 先拿到API返回的指针 pointer = api.get_pointer() # 直接从地址初始化Foo实例 foo = Foo.from_address(pointer) # 初始化完成后可直接读取/修改结构体字段 print(foo.a, foo.b, foo.c)
注意事项
- 必须保证你定义的
_fields_中字段顺序、字段类型、内存对齐规则和C端的结构体定义完全匹配,否则会出现数据错位、值异常的问题。如果C端通过#pragma pack指定了特殊对齐规则,需要在结构体类中显式声明_pack_属性,比如C端用1字节对齐时,类定义要加上_pack_ = 1。 - 通过
from_address生成的实例不持有对应内存的所有权,你需要自行保证实例使用期间,指针指向的内存块未被释放、未失效,否则会触发段错误、读到垃圾值等内存问题。
如果习惯用指针转换的写法,也可以用ctypes.cast实现完全等价的效果:
import ctypes pointer = api.get_pointer() # 将裸指针转为指向Foo类型的指针 foo_ptr = ctypes.cast(pointer, ctypes.POINTER(Foo)) # 取指针指向的内容得到结构体实例 foo = foo_ptr.contents
补充:ctypes中所有对应C类型的派生类(包括基础类型、数组、结构体、联合体)都实现了
from_address类方法,不存在结构体类型不支持该方法的情况,如果之前调用报错,可以先检查类定义是否正确、方法名是否拼写错误。
内容的提问来源于stack exchange,提问作者Sindri
相关产品推荐
相关产品推荐

