python中的记录指针,如何使用ctypes从Python的结构体中的指针访问数据?

I have the following C struct:

typedef struct {

uint8_t a;

uint8_t b;

uint32_t c;

uint8_t* d;

}

With ctypes, via a callback, I am able to obtain a pointer to such a struct in Python, let's call it ref. I can easily obtain a, b, c this way:

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

but I can't read the bytes from d. I tried the following:

d_pointer = cast(ref + 6, POINTER(POINTER(c_uint8))).contents

first_byte_of_d = d_pointer.contents

print type(first_byte_of_d) # prints

print first_byte_of_d

At this last line I encounter a SIGSEGV when debugging with gdb. So the question is, how should one access the first byte of a pointer from a struct in Python?

解决方案

You are assuming that c directly follows b which is not the case. The compiler will pad a few bytes, 2 on x86, in that structure to align c.

The proper way is to declare one-to-one mapping of your structure in ctypes:

from ctypes import *

class object_t(Structure):

_fields_ = [

('a', c_uint8),

('b', c_uint8),

('c', c_uint32),

('d', POINTER(c_uint8)),

]

No you can obtain the value of any member thought this type.

C example library:

#include

#include

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);

}

Using it from Python:

from ctypes import *

class object_t(Structure):

_fields_ = [

('a', c_uint8),

('b', c_uint8),

('c', c_uint32),

('d', POINTER(c_uint8)),

]

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))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python,直接使用C语言的指针是不支持的,因为Python是一门高级语言,对指针的处理是通过对象引用来实现的。然而,你可以使用ctypes库来调用C语言编写的动态链接库,并在Python模拟指针的操作。 以下是一个示例,展示了如何使用ctypes库来获取C语言结构的内容: ```python import ctypes # 定义C语言结构 class MyStruct(ctypes.Structure): _fields_ = [("field1", ctypes.c_int), ("field2", ctypes.c_float), ("field3", ctypes.c_char_p)] # 加载C语言编写的动态链接库 mylib = ctypes.CDLL("mylib.so") # 替换成你的动态链接库文件名及路径 # 调用C语言函数,返回结构指针 get_struct_ptr = mylib.get_struct_ptr get_struct_ptr.restype = ctypes.POINTER(MyStruct) struct_ptr = get_struct_ptr() # 通过指针获取结构的内容 my_struct = struct_ptr.contents print(my_struct.field1) print(my_struct.field2) print(my_struct.field3.decode("utf-8")) ``` 在上述示例,我们定义了一个C语言结构`MyStruct`,然后通过ctypes库加载了一个C语言编写的动态链接库。使用`restype`属性指定了返回值类型为结构指针。然后,我们调用C语言函数`get_struct_ptr`来获取结构指针,并通过`contents`属性来访问结构的内容。 需要注意的是,你需要将示例的`mylib.so`替换成你自己编译生成的动态链接库文件名及路径。此外,还需要根据你的C语言结构定义进行相应的修改。 希望对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值