我要创建一个访问windows dll函数的python脚本。我成功地访问了dll及其功能。现在,我有一个c函数
FIOSCR331_API int FIOCreateDeviceInfoList (PDEVINFO pDevInfoSet)
问题是PDEVINFO
结构。我必须在python中创建一个结构并访问这个结构。
C结构如下
typedef struct tagDEVINFO
{
char szDeviceName[MAX_PATH];
char szPCSCName[MAX_PATH];
BOOL bPassedFilter;
BOOL bUpdatePassed;
DWORD dwUpdateOrder;
DWORD dwPnP_ID;
DWORD dwFWVersion;
PDEVEXTENSION pDevExtension;
} DEVINFO, *PDEVINFO;
C函数如下
FIOSCR331_API int FIOCreateDeviceInfoList (PDEVINFO pDevInfoSet)
{
int nFIOStatus;
do
{
if ( NULL == pDevInfoSet )
{
printf("this is inside C code\n");
nFIOStatus = IDS_GENERIC_ERROR; //(200)
break;
}
else
printf ("\n%s ",pDevInfoSet->szPCSCName);
}while(false);
}
现在我实现的Python代码
class DEVINFO(Structure):
_fields_ = [("szDeviceName",c_char_p),
("szPCSCName",c_char_p),
("bPassedFilter",c_bool),
("bUpdatePassed",c_bool),
("dwUpdateOrder",c_ulong),
("dwPnp_ID",c_ulong),
("dwFWVersion",c_ulong),
("pDevExtention",DEVEXTENSION)]
lib = cdll.LoadLibrary('libFIOXXXXX.dll')
print (lib)
devInfo = DEVINFO()
devInfo.szPCSCName = c_char_p(b"this is test")
if devInfo is None:
print("hi")
else:
print("britto")
funcCreateList = lib.FIOCreateDeviceInfoList(devInfo)
print (funcCreateList)
我得到的结果是
britto
this is inside C code
200
问题是代码总是进入NULL状态,即 devInfo为NULL 。那是为什么?
新添加
在上面的python Structure DEVINFO中,它包含另一个结构DEVEXTENSION。我如何能够访问DEVEXTENSION错误的成员?
print (devInfo.pDevExtension.szName)
这引发:
AttributeError: 'LP_DEVEXTENSION" object has no attribute szName
答案 0 :(得分:3)
您的结构声明错误。它应该是:
class DEVINFO(Structure):
_fields_ = [
("szDeviceName", c_char*wintypes.MAX_PATH),
("szPCSCName", c_char*wintypes.MAX_PATH),
("bPassedFilter", wintypes.BOOL),
("bUpdatePassed", wintypes.BOOL),
("dwUpdateOrder", wintypes.DWORD),
("dwPnp_ID", wintypes.DWORD),
("dwFWVersion", wintypes.DWORD),
("pDevExtension", POINTER(DEVEXTENSION))
]
当您致电DEVINFO
时,您还必须将指针传递给FIOCreateDeviceInfoList()
结构。我会这样做:
funcCreateList = lib.FIOCreateDeviceInfoList(byref(devInfo))
正如@eryksun帮助指出的那样,添加
lib.FIOCreateDeviceInfoList.argtypes = [POINTER(DEVINFO)]
在调用FIOCreateDeviceInfoList()
之前将使ctypes
执行运行时类型检查。
答案 1 :(得分:0)
告诉ctypes FIOCreateDeviceInfoList
的参数类型是指向DEVINFO结构的指针,方法是设置argtypes
属性,如下所示:
lib.FIOCreateDeviceInfoList.argtypes = [POINTER(DEVINFO)]