Home > database >  Ctypes accessing structure member pointer to another structure
Ctypes accessing structure member pointer to another structure

Time:09-07

I'm trying to access structure pointer member pointing to another structure. Below is the scenario in my case.

c_header.h

typedef struct {
    uint8_t* addr;
    uint32_t size;
    uint8_t id;
} input_info_t;

typedef struct {
    type_t work_type;
    format_t format;
    float runtime;
    /*input*/
    input_info_t *input_info;
    /*output*/
    output_info_t *output_info;
} all_output_t;

I have casted the above structure into ctypes datatype like below

ctypes_header.py

class input_info_t(ctypes.Structure):
    _fields_ = [
        ('addr', ctypes.POINTER(ctypes.c_uint8)),
        ('size', ctypes.c_uint32),
        ('id', ctypes.c_uint8)
    ]

class output_buffer(ctypes.Structure):
    _fields_ = [
        ('work_type', type_t),
        ('format', format_option),
        ('runtime', ctypes.c_float),
        ('input_info', ctypes.POINTER(input_info_t)),
        ('output_info', ctypes.POINTER(output_info_t))
    ]

In C we will access input_info_t member from all_output_t structure, will do like

all_output_t->input_info->addr

Like the same i want to access in ctypes casted datatypes. I tried input_info.input_info_t.addr ,but getting the below error

Input addr =  <test.common.data_types.LP_input_info object at 0x7fa0ee0140>
Exception ignored on calling ctypes callback function: <function callback_function at 0x7fa111f1f0>
Traceback (most recent call last):
  File "../wrapper.py", line 61, in callback_function
    print('Input buffer length = ', buf_obj.input_info.addr)
AttributeError: 'LP_input_info' object has no attribute 'addr'

CodePudding user response:

Just like in C, pointers need to be dereferenced. In ctypes, use .contents:

import ctypes

class input_info_t(ctypes.Structure):
    _fields_ = (('addr', ctypes.POINTER(ctypes.c_uint8)),
                ('size', ctypes.c_uint32),
                ('id', ctypes.c_uint8))

# dropped fields that weren't defined by OP:
class output_buffer(ctypes.Structure):
    _fields_ = (('runtime', ctypes.c_float),
                ('input_info', ctypes.POINTER(input_info_t)))

# Initialize a sample output_buffer structure...
a = ctypes.c_uint8(123)
ibuf = input_info_t(ctypes.pointer(a), 456, 7)
obuf = output_buffer(1.5, ctypes.pointer(ibuf))

# Use .contents to dereference the two pointers.
print(obuf.input_info.contents.addr.contents.value)

Output:

123
  • Related