Как получить данные из рекурсивной структуры, полученной из функции C? - PullRequest
1 голос
/ 29 марта 2019

Я пишу обертку для устройства USB HID и хочу использовать HIDAPI для этого. В процессе написания / изучения получил указатель на рекурсивную структуру. Как я могу получить данные из этого?

Я пытался получить данные от contents, но внутри было только _field_.

C-структура и C-функция из hidapi :

struct hid_device_info {
            /** Platform-specific device path */
            char *path;
            /** Device Vendor ID */
            unsigned short vendor_id;
            /** Device Product ID */
            unsigned short product_id;
            /** Serial Number */
            wchar_t *serial_number;
            /** Device Release Number in binary-coded decimal,
                also known as Device Version Number */
            unsigned short release_number;
            /** Manufacturer String */
            wchar_t *manufacturer_string;
            /** Product string */
            wchar_t *product_string;
            /** Usage Page for this Device/Interface
                (Windows/Mac only). */
            unsigned short usage_page;
            /** Usage for this Device/Interface
                (Windows/Mac only).*/
            unsigned short usage;
            /** The USB interface which this logical device
                represents. Valid on both Linux implementations
                in all cases, and valid on the Windows implementation
                only if the device contains more than one interface. */
            int interface_number;

            /** Pointer to the next device */
            struct hid_device_info *next;
        };

struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id);

Код Python:

import ctypes


class HidDeviceInfo(ctypes.Structure):
    pass

HidDeviceInfo._field_ = [
    ('path', ctypes.c_char_p),
    ('vendor_id', ctypes.c_ushort),
    ('product_id', ctypes.c_ushort),
    ('serial_number', ctypes.c_wchar_p),
    ('release_number', ctypes.c_ushort),
    ('manufacturer_string', ctypes.c_wchar_p),
    ('product_string', ctypes.c_wchar_p),
    ('usage_page', ctypes.c_ushort),
    ('usage', ctypes.c_ushort),
    ('interface_number', ctypes.c_int),
    ('next', ctypes.POINTER(HidDeviceInfo))
]


hid_api_dll = ctypes.CDLL("hidapi.dll")

def get_devs(vid, pid):
    hid_enumerate = hid_api_dll.hid_enumerate

    hid_api_dll.hid_enumerate.argtypes = [
        ctypes.c_ushort,
        ctypes.c_ushort
    ]
    hid_api_dll.hid_enumerate.restype = ctypes.POINTER(HidDeviceInfo)

    vid_t = ctypes.c_ushort(vid)
    pid_t = ctypes.c_ushort(pid)

    res = ctypes.POINTER(HidDeviceInfo)()

    res = hid_enumerate(vid_t, pid_t)
    return res


devs = get_devs(0x0, 0x0)
print(devs.contents)
frameInfo = devs.contents
print(frameInfo.path)

Я пытаюсь просто получить атрибут path и получить AttributeError: 'HidDeviceInfo' object has no attribute 'path'.

Должен быть рекурсивный список всех скрытых устройств. Как я могу получить данные? Или, может быть, я сделал что-то не так?

1 Ответ

1 голос
/ 29 марта 2019

Согласно [Python 3]: Структуры и союзы ( выделение принадлежит мне):

Структуры и союзы должны происходить от Структура и Union базовые классы, которые определены в модуле ctypes .Каждый подкласс должен определять атрибут _fields_ . _fields_ должен представлять собой список из 2- кортежей , содержащий имя поля и тип поля .

Замените HidDeviceInfo._field_ на HidDeviceInfo._field<strong>s</strong>_ (множественное число), и все должно быть в порядке.

...