How to use ctypes void ** pointer in python3
Question: I would to connect a spectrometer by its DLL, one of function is defined as

    
    
    UINT UAI_SpectrometerOpen(unsigned int dev, void** handle, unsigned int VID,  unsigned int PID)
    

from document, dev is Specify the index for the spectrometer handle is Return
to the pointer of handle of the spectrometer VID is Provide specified VID PID
is Provide specified PID dev, VID, PID are known, but I don't know how to set
handle. my current code is as

    
    
    import ctypes
    otoDLL = ctypes.CDLL('UserApplication.dll')
    spectrometerOpen = otoDLL.UAI_SpectrometerOpen
    spectrometerOpen.argtypes = (ctypes.c_uint, ctypes.POINTER(c_void_p),
                             ctypes.c_uint, ctypes.c_uint)
    spectrometerOpen.restypes = ctypes.c_uint
    handle = ctypes.c_void_p
    errorCode = spectrometerOpen(0, handle, 1592, 2732)
    

When I run above code, I got error as

    
    
    runfile('C:/Users/Steve/Documents/Python Scripts/otoDLL.py', wdir='C:/Users/Steve/Documents/Python Scripts')
    Traceback (most recent call last):
    
      File "<ipython-input-1-73fe9922d732>", line 1, in <module>
        runfile('C:/Users/Steve/Documents/Python Scripts/otoDLL.py', wdir='C:/Users/Steve/Documents/Python Scripts')
    
      File "C:\Users\Steve\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 685, in runfile
        execfile(filename, namespace)
    
      File "C:\Users\Steve\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 85, in execfile
        exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)
    
      File "C:/Users/Steve/Documents/Python Scripts/otoDLL.py", line 5, in <module>
        spectrometerOpen.argtypes = (ctypes.c_uint, ctypes.POINTER(c_void_p),
    
    NameError: name 'c_void_p' is not defined
    

I am not familiar with ctypes and C, can anyone help me to resolve this
matter. Thanks a lot.


Answer: According to your error output:

    
    
      File "C:/Users/Steve/Documents/Python Scripts/otoDLL.py", line 5, in <module>
        spectrometerOpen.argtypes = (ctypes.c_uint, ctypes.POINTER(c_void_p),
    

You forget to put `ctypes` before `c_void_p`, thus:

    
    
    spectrometerOpen.argtypes = (ctypes.c_uint, ctypes.POINTER(ctypes.c_void_p),
                             ctypes.c_uint, ctypes.c_uint)
    

According to your function signature , the handle parameter is a pointer to a
`void*`, thus you need to pass it like this:

    
    
    import ctypes
    otoDLL = ctypes.CDLL('UserApplication.dll')
    spectrometerOpen = otoDLL.UAI_SpectrometerOpen
    spectrometerOpen.argtypes = (ctypes.c_uint, ctypes.POINTER(ctypes.c_void_p),
                             ctypes.c_uint, ctypes.c_uint)
    spectrometerOpen.restypes = ctypes.c_uint
    
    # declare HANDLE type, which is a void*
    HANDLE = ctypes.c_void_p
    
    # example: declare an instance of HANDLE, set to NULL (0)
    my_handle = HANDLE(0)
    
    #pass the handle by reference (works like passing a void**)
    errorCode = spectrometerOpen(0, ctypes.byref(my_handle), 1592, 2732)
    

Note: this is just an example, you should check the documentation of the
`spectrometerOpen` function to see what exactly it is awaiting exactly for the
`handle` parameter (can it be NULL, what type is it exactly, etc.).

