Search code examples
pythoncintrospection

Introspecting nested ctypes structures


Similarly to this question, I would like to print the members of a C structure from Python.

I implemented the following function:

def print_ctypes_obj(obj, indent=0):
    for fname, fvalue in obj._fields_:
        if hasattr(fvalue, '_fields_'):
            print_ctypes_obj(fvalue, indent+4)
        else:
            print '{}{} = {}'.format(' '*indent, fname, getattr(obj, fname))

The idea is that if the field itself has a _fields_ attribute, then it is a structure, otherwise a normal field so print it. The recursion works fine, but after the first level I'm getting repr strings printed instead of values. For example:

foo = 1
bar = 2
baz = 3
    innerFoo = <Field type=c_long, ofs=0, size=4>
    innerBar = <Field type=c_long, ofs=4, size=4>
    innerBaz = <Field type=c_long, ofs=8, size=4>
quz = 4

The output I'm expecting would be something like:

foo = 1
bar = 2
baz = 3
    innerFoo = 5
    innerBar = 23
    innerBaz = 56
quz = 4

What is my mistake here?


Solution

  • The solution is pretty simple.

    When printing the nested structures, I still need to get the structure as an attribute so ctypes can perform its magic:

    print_ctypes_obj(getattr(obj, fname), indent+4)
    

    (another issue with the code is the naming of the iterated pairs; they should be fname, ftype instead of fname, fvalue which is incorrect and misleading)