我查过其他的答案,但似乎没法解决这个问题。我试图调用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;
我认为在DLL填充数据数组时,必须为地址、命令和BlockLength设置值。 需要此结构的函数将其作为指针
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的值会返回“测试字符串”,因此不会有任何更改。 任何关于这里可能发生的事情的建议都将不胜感激。
谢谢
更新:
既然我有几次询问我的手柄是否正确,下面是我的使用方法。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
你就快到了。应该使用
c_char * SMB_MAX_DATA_SIZE
作为Data
定义的类型。这在Mac OS X上对我有效:共享库:
Python驱动程序:
更新
您遇到了问题,因为需要将结果类型
open_smbus
设置为void*
。默认情况下,ctypes假设函数返回int
s因为您使用的是
c_void_p()
,所以出现了一个错误(请注意额外的括号)。在c_void_p
和c_void_p()
之间有一个重要的区别。前者是一个类型,后者是一个实例类型。c_void_p
表示C类型void*
,而c_void_p()
表示实际的指针实例(默认值为0)。这是一个有效的例子。看起来您传递给函数的类型不正确。
测试DLL代码(在Windows上为“cl/W4/LD x.c”)
Python代码
输出
尝试改变
到
相关问题 更多 >
编程相关推荐