I'm having trouble accessing elements in structures that are embedded within other structures using Python ctypes.
Here is the C:
struct GSList
{
void* data;
GSList* next;
};
struct att_range
{
uint16_t start;
uint16_t end;
};
struct gatt_primary
{
char uuid[38];
int changed;
struct att_range* range;
};
typedef void( *python_callback_t )( GSList* services );
static python_callback_t pycb = NULL;
// pycb is set to a valid function pointer before the callback below is called.
static void primary_all_cb( GSList *services, uint8_t status )
{
if( status == 0 ) {
pycb( services );
}
}
Here is the Python:
import ctypes
# CDLL is used to access a shared library that contains the C code above
class range(ctypes.Structure):
_fields_ = [
('starthnd', ctypes.c_uint16),
('endhnd', ctypes.c_uint16)
]
class service(ctypes.Structure):
_fields_ = [
('uuid', ctypes.c_char_p),
('changed', ctypes.c_int),
('range', ctypes.POINTER(range))
]
class servicelist(ctypes.Structure):
pass
servicelist._fields_ = [
('data', ctypes.POINTER(service)),
('next', ctypes.POINTER(servicelist))
]
CB_FUNC_TYPE = ctypes.CFUNCTYPE(None, ctypes.POINTER(servicelist))
def cb(csvclist):
svclist = ctypes.cast(csvclist, ctypes.POINTER(servicelist))
data = ctypes.cast(svclist.contents.data, ctypes.POINTER(service))
next = ctypes.cast(svclist.contents.next, ctypes.POINTER(servicelist))
hndrange = ctypes.cast(data.contents.range, ctypes.POINTER(range))
starthnd = ctypes.cast(hndrange.contents.starthnd, ctypes.c_uint16)
endhnd = ctypes.cast(hndrange.contents.endhnd.contents, ctypes.c_uint16)
uuid = ctypes.cast(data.contents.uuid, ctypes.c_char_p)
print('start: 0x%X, end: 0x%X, uuid: %s' % (starthnd, endhnd, uuid))
cb_func = CB_FUNC_TYPE(cb)
// gatt is the shared library. ble_start source is not shown here, but it sets the callback function pointer.
gatt.ble_start(cb_func)
I'm using Python 3.4 and gcc 4.7. This does not include the functions initially called to trigger the callback function or the Python code to access the shared library. I've verified that all the information does fill the structures in C and have been able to print the contents of the uuid in Python at one point. I get a segmentation fault when I try to access hndrange. I can print out the object reference of hndrange in Python, but if I try to access the elements, I get a segmentation fault.
What am I doing wrong?
Any help is appreciated.