3

I am to create a python script that will access a windows dll function. I was successful in accessing the dll and its functions. Now that, I have a c function as

FIOSCR331_API int FIOCreateDeviceInfoList (PDEVINFO pDevInfoSet)

the problem is the PDEVINFO structure. I must create a structure in python and access this structure.

The C structure is as follows

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;

the C function is as follows

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);
}

Now the Python code I implemented

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)

The Result I got is

britto
this is inside C code
200

The problem is the code goes into NULL condition always, i.e. devInfo is NULL. Why is that?

NEWLY ADDED

In the above python Structure DEVINFO, It contains another structure DEVEXTENSION. How will i be able to access the members of the DEVEXTENSION error??

print (devInfo.pDevExtension.szName)

This throws:

AttributeError: 'LP_DEVEXTENSION" object has no attribute szName
1
  • For your follow up question on 10-29, use either devInfo.pDevExtension[0].szName or devInfo.pDevExtension.contents.szName. Commented Oct 31, 2012 at 15:12

2 Answers 2

4

Your structure declaration is wrong. It should be:

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

You must also pass a pointer to the DEVINFO struct when you call FIOCreateDeviceInfoList(). I'd do it like this:

funcCreateList = lib.FIOCreateDeviceInfoList(byref(devInfo))

As @eryksun helpfully points out, adding

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

before the call to FIOCreateDeviceInfoList() will make ctypes perform runtime type checking.

Sign up to request clarification or add additional context in comments.

9 Comments

To be type safe set lib.FIOCreateDeviceInfoList.argtypes = [POINTER(DEVINFO)].
@eryksun Will that apply runtime type checking?
Yes: ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected LP_DEVINFO instance instead of str. It beats a segfault.
@eryksun Thanks. I hadn't considered that. But you make an excellent point.
@Britto: Note that this creates character arrays inline in the memory allocated for the structure. Don't set the value with a c_char_p; just use, for example, devInfo.szPCSCName = b"this is a test". The _ctypes.CField handles copying the bytes into the structure.
|
0

Tell ctypes that the type of the argument to FIOCreateDeviceInfoList is a pointer to a DEVINFO structure by setting its argtypes attribute as follows:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.