简体   繁体   中英

How to use ctypes void ** pointer in python3

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM