我浏览了其他答案,但好像无法让这个功能正常工作。我正在尝试调用一个与SMBus设备通信的DLL中的函数。此函数需要一个结构体指针作为参数,其中包含一个数组作为其字段之一。所以...
在C语言中:
这将回应以下内容:
不,没有错误。然而,当我尝试将此传递给函数时:
我尝试了转换,但仍然不起作用。有人能为我解释一下吗?
更新:
如果我首先像这样初始化结构体:
我没有收到错误信息。但是,当函数成功时应该返回'0',失败时应该返回非零值,但它返回了'-1'。检查smb_request.Data的值仍然是'a test string',因此没有任何变化。如果您有任何建议,请告诉我,谢谢。
更新:由于有一些人询问我的句柄是否正确,所以我在这里解释一下。DLL的头文件声明如下:
在调用 smbus_read_byte() 之前,我会先执行这段代码。我试过设置
在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))
我能理解:
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))
我没有收到错误信息。但是,当函数成功时应该返回'0',失败时应该返回非零值,但它返回了'-1'。检查smb_request.Data的值仍然是'a test string',因此没有任何变化。如果您有任何建议,请告诉我,谢谢。
更新:由于有一些人询问我的句柄是否正确,所以我在这里解释一下。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
。