我已经查看了其他答案,但似乎无法使其发挥作用。我正在尝试调用 DLL 中的函数来与 SMBus 设备进行通信。该函数接受一个指向结构的指针,该结构有一个数组作为其字段之一。所以...
In C:
typedef struct _SMB_REQUEST
{
unsigned char Address;
unsigned char Command;
unsigned char BlockLength;
unsigned char Data[SMB_MAX_DATA_SIZE];
} SMB_REQUEST;
我想我必须在 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))
I get:
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))
我尝试过铸造,但仍然不行。有人能为我解释一下吗?
Update:
如果我首先像这样初始化结构:
smb_request = SMB_REQUEST('\xA6', '\x00', chr(1), 'a test string')
然后参考低音:
int_response = smbus_receive_byte(smbus_handle, ctypes.byref(smb_request))
我没有收到任何错误。然而,当该函数应该返回“0”表示成功并且返回非零表示失败时,该函数会返回 -1。检查 smb_request.Data 的值会返回“测试字符串”,因此没有任何变化。
任何有关这里可能发生的情况的建议将不胜感激。
Thanks
UPDATE:
由于我收到了一些关于我的句柄是否正确的询问,以下是我使用它的方式。 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