gpt4 book ai didi

python - 从 python 访问 C 结构

转载 作者:行者123 更新时间:2023-12-02 06:40:25 26 4
gpt4 key购买 nike

我要创建一个Python脚本来访问Windows DLL函数。我成功地访问了 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结构DEVINFO中,它包含另一个结构DEVEXTENSION。我如何才能访问 DEVEXTENSION 错误的成员?

print (devInfo.pDevExtension.szName)

这会抛出:

AttributeError: 'LP_DEVEXTENSION" object has no attribute szName

最佳答案

您的结构声明是错误的。应该是:

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))
]

当您调用 FIOCreateDeviceInfoList() 时,您还必须传递一个指向 DEVINFO 结构的指针。我会这样做:

funcCreateList = lib.FIOCreateDeviceInfoList(byref(devInfo))

正如 @eryksun 所指出的,添加

lib.FIOCreateDeviceInfoList.argtypes = [POINTER(DEVINFO)]

在调用 FIOCreateDeviceInfoList() 之前,ctypes 会执行运行时类型检查。

关于python - 从 python 访问 C 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13100852/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com