如何使用ctypes从Python中访问struct中的指针数据?
发布时间:2020-12-20 11:36:36 所属栏目:Python 来源:网络整理
导读:我有以下C结构: typedef struct { uint8_t a; uint8_t b; uint32_t c; uint8_t* d;} 使用ctypes,通过回调,我能够在Python中获得指向这样一个结构的指针,让我们称之为ref.我可以这样轻松地获得a,b,c: from ctypes import cast,c_uint8,c_uint32,POINTERa =
我有以下C结构:
typedef struct { uint8_t a; uint8_t b; uint32_t c; uint8_t* d; } 使用ctypes,通过回调,我能够在Python中获得指向这样一个结构的指针,让我们称之为ref.我可以这样轻松地获得a,b,c: from ctypes import cast,c_uint8,c_uint32,POINTER a = cast(ref,POINTER(c_uint8)).contents.value b = cast(ref + 1,POINTER(c_uint8)).contents.value c = cast(ref + 2,POINTER(c_uint32)).contents.value 但我无法从d读取字节.我尝试了以下方法: d_pointer = cast(ref + 6,POINTER(POINTER(c_uint8))).contents first_byte_of_d = d_pointer.contents print type(first_byte_of_d) # prints <class 'ctypes.c_ubyte'> print first_byte_of_d 在最后一行,我在使用gdb进行调试时遇到了SIGSEGV.所以问题是,如何从Python中的结构访问指针的第一个字节? 解决方法
你假设c直接跟随b,但事实并非如此.编译器将在该结构中填充x86上的几个字节,以对齐c.
正确的方法是在ctypes中声明结构的一对一映射: from ctypes import * class object_t(Structure): _fields_ = [ ('a',c_uint8),('b',('c',c_uint32),('d',POINTER(c_uint8)),] 不,您可以获得此类型的任何成员的价值. C示例库: #include <stdint.h> #include <stdlib.h> struct object_t { uint8_t a; uint8_t b; uint32_t c; uint8_t* d; }; static struct object_t object = {'a','b',12345,NULL}; struct object_t * func1(void) { return &object; } void func2(void(*callback)(struct object_t *)) { callback(&object); } 从Python使用它: from ctypes import * class object_t(Structure): _fields_ = [ ('a',] callback_t = CFUNCTYPE(None,POINTER(object_t)) lib = CDLL('./file.dll') func1 = lib.func1 func1.argtypes = None func1.restype = POINTER(object_t) func2 = lib.func2 func2.argtypes = [callback_t] func2.restype = None ret = func1() a = ret.contents.a b = ret.contents.b c = ret.contents.c d = ret.contents.d def mycallback(obj): a = obj.contents.a b = obj.contents.b c = obj.contents.c d = obj.contents.d func2(callback_t(mycallback)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |