打印所有ctypes“结构”字段内省 [英] Print all fields of ctypes "Structure" with introspection

查看:83
本文介绍了打印所有ctypes“结构”字段内省的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

test.c:

#include <stdio.h>
#include <stdlib.h>

struct s {
    char a;
    int b;
    float c;
    double d;
};

struct s *create_struct()
{
    struct s *res = malloc(sizeof(struct s));
    res->a = 1; res->b = 2; res->c = 3.0f; res->d = 4.0;
    return res;
}

test.py:

from ctypes import *

class S(Structure):
    _fields_ = [
        ('a', c_byte),
        ('b', c_int),
        ('c', c_float),
        ('d', c_double)
    ]

lib = CDLL('./test.so')

create_struct = lib.create_struct
create_struct.restype = POINTER(S)
create_struct.argtypes = []

s_ptr = create_struct()
s = s_ptr.contents

print s._fields_[0][0], s.a
print s._fields_[1][0], s.b
print s._fields_[2][0], s.c
print s._fields_[3][0], s.d
print s.__dict__

输出:

a 1
b 2
c 3.0
d 4.0
{}

I' d想改写上面的python脚本来打印我s结构的每个字段,而不必对每个字段进行显式操作。据我了解,可以使用__dict__属性完成此操作,但是我的属性为空。有没有办法对扩展ctypes.Structure的类执行此操作?

I'd like to adapt the python script above to print each field of my s structure without having to do explicitly for each field. From what I understand, this can be done using the __dict__ attribute but mine is empty. Is there any way to do this for a class that extends ctypes.Structure?

推荐答案

如何使用 getattr

>>> from ctypes import *
>>>
>>> class S(Structure):
...     _fields_ = [
...         ('a', c_byte),
...         ('b', c_int),
...         ('c', c_float),
...         ('d', c_double)
...     ]
...
>>> s = S(1, 2, 3, 4.0)
>>>
>>> for field_name, field_type in s._fields_:
...     print field_name, getattr(s, field_name)
...
a 1
b 2
c 3.0
d 4.0

更新

如果结构(或联合)中有一个位域,则迭代 _fields _ 会产生3个元组,这将导致 ValueError 。为了防止这种情况,您需要调整代码:

If there is a bitfield in the structure (or union), iterating _fields_ yield a tuple of 3 items which will cause ValueError. To prevent that you need to adjust the code:

...

for field in s._fields_:
    print field[0], getattr(s, field[0])

这篇关于打印所有ctypes“结构”字段内省的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆