如何从C函数获得的递归结构中获取数据?

时间:2019-03-29 11:56:18

标签: c python-3.x ctypes hidapi

我正在为USB隐藏设备编写包装器,并希望为此使用hidapi。在编写/学习过程中,有一个关于递归结构的指针。如何从中获取数据?

我试图从contents获取数据,但是里面只有_field_

hidapi中的C结构和C函数:

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 个答案:

答案 0 :(得分:1)

根据[Python 3]: Structures and unions强调是我的):

  

结构和联合必须派生自Structure模块中定义的Unionctypes基类。每个子类必须定义一个 _fields _ 属性 _fields _ 必须是2个元组的列表,其中包含字段名称字段类型

HidDeviceInfo._field_替换为HidDeviceInfo._fields_(复数),一切都会好起来的。