Как получить объект типа ctypes из массива ctypes

На самом деле, я пытаюсь преобразовать массивы ctypes в списки python и обратно.

Если найден этот поток. Но предполагается, что мы знаем тип во время компиляции.

Но можно ли получить тип ctypes для элемента?

У меня есть список Python, который содержит хотя бы один элемент. Я хочу сделать что-то подобное

import ctypes
arr = (type(pyarr[0]) * len(pyarr))(*pyarr)

Это явно не работает, потому что type() не возвращает класс, совместимый с ctypes. Но даже если список содержит объект, созданный непосредственно из ctypes, приведенный выше код не работает, потому что это экземпляр объекта типа.

Есть ли способ выполнить эту задачу?

[ИЗМЕНИТЬ]

Хорошо, вот код, который работает для меня. Я использую его для преобразования входных параметров из метода сервера comtypes в списки python и возвращаемых значений в указатели массива:

def list(count, p_items):
    """Returns a python list for the given times represented by a pointer and the number of items"""
    items = []
    for i in range(count):
        items.append(p_items[i])
    return items

def p_list(items):
    """Returns a pointer to a list of items"""
    c_items = (type(items[0])*len(items))(*items)
    p_items = cast(c_items, POINTER(type(items[0])))

    return p_items

Как объяснялось ранее, для p_list(items) требуется как минимум один элемент.


person jaw    schedule 29.03.2012    source источник


Ответы (1)


Я не думаю, что это возможно напрямую, потому что несколько типов ctypes сопоставляются с одним типом Python. Например, c_int/c_long/c_ulong/c_ulonglong все сопоставляются с Python int. Какой тип вы бы выбрали? Вы можете создать карту своих предпочтений:

>>> D = {int:c_int,float:c_double}
>>> pyarr = [1.2,2.4,3.6]
>>> arr = (D[type(pyarr[0])] * len(pyarr))(*pyarr)
>>> arr
<__main__.c_double_Array_3 object at 0x023540D0>
>>> arr[0]
1.2
>>> arr[1]
2.4
>>> arr[2]
3.6

Кроме того, недокументированный _type_ может указать тип массива ctypes.

>>> arr._type_
<class 'ctypes.c_double'>
person Mark Tolonen    schedule 30.03.2012
comment
Ты прав. На самом деле моя проблема заключалась в том, что я сделал что-то вроде error = HRESULT();error = E_FAIL. Затем ошибка была добавлена ​​в список, который я хотел преобразовать. Проблема заключалась в том, что E_FAIL имел тип int, а не HRESULT. Так что и error = HRESULT(E_FAIL), и error = HRESULT(); (...) error.value = E_FAIL работают. - person jaw; 30.03.2012
comment
Большое спасибо, что недокументированный обр._тип_ был как раз то, что мне было нужно - person mrkbutty; 06.02.2021