Python и Ctypes: передача структуры функции в качестве указателя для получения данных

Я просмотрел другие ответы, но не могу заставить это работать. Я пытаюсь вызвать функцию в DLL для связи с устройствами SMBus. Эта функция принимает указатель на структуру, одним из полей которой является массив. так что ...

В C:

typedef struct _SMB_REQUEST
{
    unsigned char Address;
    unsigned char Command;
    unsigned char BlockLength;
    unsigned char Data[SMB_MAX_DATA_SIZE];
} SMB_REQUEST;

Я думаю, мне нужно установить значения для Address, Command и BlockLength, пока DLL заполняет массив данных. The function that requires this struct takes it as a pointer

SMBUS_API int SmBusReadByte( SMBUS_HANDLE handle, SMB_REQUEST *request );

So I've set up the struct in Python like so:

class SMB_REQUEST(ctypes.Structure):
    _fields_ = [("Address", c_char),
            ("Command", c_char),
            ("BlockLength", c_char),
            ("Data", type(create_string_buffer(SMB_MAX_DATA_SIZE))]

*Note: I've also tried ctypes.c_char*SMB_MAX_DATA_SIZE for the data type*

To pass a pointer to a struct of this type to the function I have tried to initialise it first as follows:

data = create_string_buffer(SMB_MAX_DATA_SIZE)
smb_request = SMB_REQUEST('\x53', \x00', 1, data)

This responds with:

TypeError: expected string or Unicode object, c_char_Array_32 found

If I try leaving out the data array, like so:

smb_request = SMB_REQUEST('\x53', \x00', 1)

No, error. Однако затем, когда я пытаюсь передать это функции:

int_response =  smbus_read_byte(smbus_handle, smb_request))

, я получаю:

ArgumentError: argument 2: <type 'exceptions.TypeError'>: expected LP_SMB_REQUES
T instance instead of SMB_REQUEST

Я пытался передать его как указатель:

int_response =  smbus_read_byte(smbus_handle, ctypes.POINTER(smb_request))

и получаю:

----> 1
      2
      3
      4
      5

TypeError: must be a ctypes type

Вот как я настроил типы искусства:

smbus_read_byte.argtypes = (ctypes.c_void_p, ctypes.POINTER(SMB_REQUEST))

Я пробовал кастинг, но все равно не пошел. Может ли кто-нибудь пролить свет на это для меня?

Обновление:

Если я сначала инициализирую структуру следующим образом:

smb_request = SMB_REQUEST('\xA6', '\x00', chr(1), 'a test string')

, а затем бас по ссылке:

int_response =  smbus_receive_byte(smbus_handle, ctypes.byref(smb_request))

, я не получу ошибки. Однако функция возвращает -1, если она должна вернуть «0» в случае успеха и ненулевое значение в случае неудачи. Проверка значения smb_request.Data возвращает «тестовую строку», поэтому никаких изменений в ней нет. Мы будем очень благодарны за любые предложения относительно того, что здесь может происходить.

Спасибо

ОБНОВЛЕНИЕ:

Так как я получил пару вопросов о правильности моего дескриптора, вот как я его использую . Заголовочный файл для DLL объявляет следующее:

typedef void *SMBUS_HANDLE;

//
// This function call initializes the SMBus, opens the driver and 
// allocates the resources associated with the SMBus.
// All SMBus API calls are valid 
// after making this call except to re-open the SMBus.
//
SMBUS_API SMBUS_HANDLE OpenSmbus(void);

Итак, вот как я это делаю в python:

smbus_handle = c_void_p() # NOTE: I have also tried it without this line but same result

open_smbus = CDLL('smbus.dll').OpenSmbus
smbus_handle =  open_smbus()
print 'SMBUS_API SMBUS_HANDLE OpenSmbus(void): ' + str(smbus_handle)

Я вызываю это перед вызовом smbus_read_byte (). Я пробовал установить open_smbus.restype = c_void_p () , но получаю сообщение об ошибке: TypeError: restype должен быть типом, вызываемым или None

16
задан Jack 5 December 2010 в 01:00
поделиться