3

我将创建一个将访问 windows dll 函数的 python 脚本。我成功访问了 dll 及其功能。现在,我有 ac 功能

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
4

2 回答 2

4

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

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执行运行时类型检查之前。

于 2012-10-27T16:03:21.367 回答
0

告诉 ctypes 参数的类型FIOCreateDeviceInfoList是指向 DEVINFO 结构的指针,方法是argtypes如下设置它的属性:

lib.FIOCreateDeviceInfoList.argtypes = [POINTER(DEVINFO)]
于 2012-10-27T15:56:30.747 回答