简体   繁体   中英

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?

Try this:

def check_interfaces(some_num):
    FOOBAR.CheckInterfaces.restype = ct.c_bool
    FOOBAR.CheckInterfaces.argtypes = [
        ct.c_ushort,
        ct.POINTER(ct.c_ushort),
        ct.POINTER(ct.POINTER(CardInfo)),
    ]

    num_cards = ct.c_ushort(0)
    card_info_array = (CardInfo * 16)()
    status = FOOBAR.CheckInterfaces(some_num, ct.byref(num_cards), ct.byref(card_info_array))
    return [card_info_array[i] for i in range(num_cards)]

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)
    ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM