Search code examples
pythonc++dllctypessafearray

Safearray in Python for Ctypes


I was trying to use a function in DLL provided using Python Ctypes. I do know that writing a code in C++ would be more efficient and nice option. However, everything in my project is written in Python. So it would take a while for me to convert this code into C++.

The function that I would like to use from the DLL is something like this

int MLAPI_GetDeviceInfo(SAFEARRAY**, SAFEARRAY**) 

As you know, ctypes does not have a data type called SAFEARRAY. So I was trying to make a Structure by Class and fields. (Actually there was someone who tried to make SAFEARRAY when I Googled, however, it did not work for me , also looked for similar cases here )

from ctypes import *
class SAFEARRAYBOUND(Structure):
    _fields_ = [("cElements" , c_ulong),
                ("lLbound" , c_long)]


class SAFEARRAY(Structure):
    _fields_ = [("cDims", c_ushort),
                ("fFeatures", c_ushort),
                ("cbElements", c_ulong),
                ("cLocks", c_ulong),
                ("pvData", c_void_p),
                ("rgsabound", SAFEARRAYBOUND * 1)]

As the structure declaration says in the official document, I wrote two classes about SAFEARRAY and SAFEARRAYBOUND.

Then I wrote the code using ctypes for function use.

getdevicedata = Dll['MLAPI_GetDeviceInfo']
getdevicedata.restype = c_int
getdevicedata.argtypes = ()
getdevicedata()

I was quite unsure what to write for argtypes. Also, I am quite unsure what to put as arguments for getdevicedata function that I have wrote. These are pretty much of my code. I tried bunch of combinations for the arguments but everything failed. So I came to Stackoverflow for your answers...

I am quite noob to Stackoverflow and Python, so if I had made a mistake within this forum or code (or both) please let me know. Thanks for reading. Have a nice day.


Solution

  • Assuming your structures are correct (note they need more work since the arrays are of variable size), the .argtypes is:

    getdevicedata.argtypes = POINTER(POINTER(SAFEARRAY)),POINTER(POINTER(SAFEARRAY))