Skip to content Skip to sidebar Skip to footer

Ctypes: Get A Pointer To A Struct Field

I need to get a pointer with the address of a struct field. Important: I'm builduing a serializer for a set of c structs so i want to iterate over the fields of a struct and get th

Solution 1:

Here's a way...

The class variable Test._fields_ defines the attributes and their C types. The class attributes generated by assigning the fields contain information about the offset for that attribute, for example:

>>> Test.a
<Field type=c_long, ofs=0, size=4>
>>> Test.b
<Field type=c_double, ofs=8, size=8>
>>> Test.c
<Field type=c_char_Array_10, ofs=16, size=10>

For each type, the from_buffer() method builds a C type using the same data buffer as an existing type. An instance of the structure implements the buffer API required to access its data, so if you know the offset of a structure element's data, you can generate a ctypes type that references the same data, and create a pointer to it.

from ctypes import *

class Test(Structure):
    _fields_ = [('a',c_int),
                ('b',c_double),
                ('c',c_char * 10)]

x = Test(1,2.5,b'abc')

for field,ftype in Test._fields_:

    # Look up each attribute in the class, and get its offset.
    ofs = getattr(Test,field).offset

    # Create a pointer to the same field type using the same data.
    p = pointer(ftype.from_buffer(x,ofs))
    print(p,p.contents)

Output:

<__main__.LP_c_long object at 0x000001932DE0EEC8> c_long(1)
<__main__.LP_c_double object at 0x000001932DE0ECC8> c_double(2.5)
<__main__.LP_c_char_Array_10 object at 0x000001932DE0EDC8> <__main__.c_char_Array_10 object at 0x000001932DE0ECC8>

Post a Comment for "Ctypes: Get A Pointer To A Struct Field"