Указатели и массивы в Python ctypes

У меня есть DLL, содержащая функцию C с прототипом, как это:

int c_read_block(uint32 addr, uint32 *buf, uint32 num);

Я хочу вызвать его из Python, используя ctypes. Функция ожидает указатель на кусок памяти, в который она будет записывать результаты. Я нене знаю, как построить и передать такой кусок памяти. Документация ctypes отсутствуетбольшая помощь

Построение массива и его передача »ByRef», как это:

    cresult = (c_ulong * num)()
    err = self.c_read_block(addr, byref(cresult), num)

Дает это сообщение об ошибке:

ArgumentError: argument 3: : expected LP_c_ulong instance instead of pointer to c_ulong_Array_2

Я думаю, это потому, что массив Python ulong не похож на массив c uint32. Должен ли я использоватьcreate_char_string, Если да, то как мне убедить Python вбросать" этот буфер для LP_c_ulong?

Ответы на вопрос(3)

Решение Вопроса

Вы можете сыграть сcast функция :)

>>> import ctypes
>>> x = (ctypes.c_ulong*5)()
>>> x
<__main__.c_ulong_Array_5 object at 0x00C2DB20>
>>> ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong))
<__main__.LP_c_ulong object at 0x0119FD00>
>>> 
 Frederick The Fool16 мая 2010 г., 08:52
Спасибо. Я тоже нашел это полезным.
 Charles Grunwald24 дек. 2016 г., 14:21
LP_c_ulong_Array_5 будет адрес, указывающий на адрес, указывающий на первый элемент в массивеuint32с, тогда как ОП 'Функция s ищет адрес, указывающий на первый элемент массива.LP_c_ulong_Array_5 будет для такой функции, как:int c_read_block(uint32 addr, uint32 *buf[], uint32 num);
 Andrew Bainbridge01 сент. 2009 г., 18:15
Превосходно. Благодарю. Есть ли какая-то документация, из которой вы почерпнули эти знания?
 David Poole09 дек. 2009 г., 16:13
Спасибо! Это тоже заставило меня заработать.
 Mike Vella02 июн. 2015 г., 18:24
Почему я этоLP_c_ulong объект, а неLP_c_ulong_Array_5 объект
 Mark Rushakoff01 сент. 2009 г., 18:20
мы использовалиctypes несколько раз и ямы сталкивались с этим в связанной документации раньше.

вам необходимо привестиPOINTER(list of ulong)

In [33]: ptr = ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong*5))
In [34]: ptr
Out[34]: <__main__.LP_c_ulong_Array_5 at 0x23e2560>

ctypes позволяет использовать массив вместо указателя напрямую. Проблема заключается вbyref в вашем коде (который будет эквивалентно указателю на указатель):

Так что вместо:

cresult = (c_ulong * num)()
err = self.c_read_block(addr, byref(cresult), num)

пытаться:

cresult = (c_ulong * num)()
err = self.c_read_block(addr, cresult, num)

Ваш ответ на вопрос