Search code examples
pythonctypes

ctypes output structure pointer array


I'm trying to wrap an API, that has a lot of functions where it returns a status (no issue there), but the actual output is a structure pointer array. I'm having trouble getting a useful structure back. All of the documentation I've found so far handles returns instead of pointer outputs. This is what everything looks like.

foobar.h

typedef struct
{
    unsigned short  serialNumber;
    unsigned char   ipAddr[4];
} CardInfo;

FOOBARSHARED_EXPORT bool CheckInterfaces( unsigned short someNum,   // input
                                          unsigned short *numCards, // output
                                          CardInfo **pCardInfo );   // output

My attempt at wrapping it looks like this:

foobar.py

import ctypes as ct

FOOBAR = ct.CDLL('FOOBAR.dll')

class CardInfo(ct.Structure):
    __fields__ = [
        ('serialNumber', ct.c_ushort),
        ('ipAddr', ct.c_char*4)
    ]

def check_interfaces(some_num):
    FOOBAR.CheckInterfaces.argtypes = [
        ct.c_ushort, ct.POINTER(ct.c_ushort), ct.POINTER(ct.POINTER(CardInfo))
    ]
    FOOBAR.CheckInterfaces.restype = ct.c_bool
    num_cards = ct.c_ushort(0)
    card_info_pointer = ct.POINTER(CardInfo)()
    status = FOOBAR.CheckInterfaces(some_num, ct.byref(num_cards), ct.byref(card_info_pointer))
    return [card_info_pointer[i] for i in range(num_cards)]

This does in fact return a list of CardInfo objects, but none of the fields are there. Any ideas about what I'm missing?


Solution

  • Thanks to Mark Tolonen's comment. I didn't notice that the correct structure field is _fields_ not __fields__

    The correct structure should have been:

    class CardInfo(ct.Structure):
        _fields_ = [
            ('serialNumber', ct.c_ushort),
            ('ipAddr', ct.c_char*4)
        ]