加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

如何使用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))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读