Вопрос

У меня есть 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: <type 'exceptions.TypeError'>: expected LP_c_ulong instance instead of pointer to c_ulong_Array_2

Я думаю, это потому, что массив Python Ulong не похож на массив AC UINT32. Я должен использовать create_char_string. Анкет Если да, то как мне убедить Python «разыграть» этот буфер в LP_C_ULONG?

Это было полезно?

Решение

Вы можете бросить с 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>
>>> 

Другие советы

Вы можете отдать результат, но 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)

В решении есть опечатка. Чтобы получить указатель на множество Ulongs, вам нужно поднять на 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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top