Я просмотрел другие ответы, но не могу заставить это работать.Я пытаюсь вызвать функцию в 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 заполняет массив данных.Функция, которая требует эту структуру, принимает ее как указатель
SMBUS_API int SmBusReadByte( SMBUS_HANDLE handle, SMB_REQUEST *request );
Так что я настроил структуру в Python так:
class SMB_REQUEST(ctypes.Structure):
_fields_ = [("Address", c_char),
("Command", c_char),
("BlockLength", c_char),
("Data", type(create_string_buffer(SMB_MAX_DATA_SIZE))]
* Примечание: я также пыталсяctypes.c_char * SMB_MAX_DATA_SIZE для типа данных *
Чтобы передать указатель на структуру этого типа в функцию, я попытался сначала инициализировать ее следующим образом:
data = create_string_buffer(SMB_MAX_DATA_SIZE)
smb_request = SMB_REQUEST('\x53', \x00', 1, data)
Это отвечаетс:
TypeError: expected string or Unicode object, c_char_Array_32 found
Если я попытаюсь пропустить массив данных, например:
smb_request = SMB_REQUEST('\x53', \x00', 1)
Нет, ошибка.Однако затем, когда я пытаюсь передать это функции:
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 must be a type, a callable, or None