I am working with a DLL called CL3_IF.dll that is described in its documentation as:
Format: CL3IF_VERSION_INFO CL3IF_GetVersion(void)
Parameters: —
Return value: Returns the version of this DLL.
typedef struct {
INT majorNumber;
INT minorNumber;
INT revisionNumber;
INT buildNumber;
} CL3IF_VERSION_INFO;
Explanation: This function gets the DLL version.
I have used the following python code:
import ctypes
CLP=ctypes.WinDLL('CL3_IF.dll')
class CLIF_VERSION_INFO(ctypes.Structure):
_fields_ = [("majorNumber", ctypes.c_int),
("minorNumber", ctypes.c_int),
("revisionNumber", ctypes.c_int),
("buildNumber", ctypes.c_int)]
CLP.CL3IF_GetVersion(ctypes.c_void_p, CLIF_VERSION_INFO)
When I run the above code I get the following error:
ArgumentError: argument 1: <class 'TypeError'>: Don't know how to convert parameter 1
I want to be able to get the version info in a usable form, and many other functions of the dll give their outputs in complex structures.
The most complex function I will be using will be this
If anybody knows how I would go about reading the output of this, I would greatly appreciate it.
The returned structure is a return value, not an argument, and void
means no parameters, whereas c_void_p
means a void*
parameter. Make sure to set .argtypes
and .restype
correctly.
Also note that WinDLL
is for 32-bit __stdcall
APIs. Use CDLL
for __cdecl
(C calling convention) APIs. On 64-bit Python both will work, because there is only one calling convention, but for portable code use the correct one.
Full example below:
test.cpp
#ifdef _WIN32
# define API __declspec(dllexport)
#else
# define API
#endif
typedef int INT;
typedef struct {
INT majorNumber;
INT minorNumber;
INT revisionNumber;
INT buildNumber;
} CL3IF_VERSION_INFO;
extern "C"
{
API CL3IF_VERSION_INFO CL3IF_GetVersion(void) {
CL3IF_VERSION_INFO info = {1,2,3,4};
return info;
}
}
test.py
import ctypes
class CLIF_VERSION_INFO(ctypes.Structure):
_fields_ = [("majorNumber", ctypes.c_int),
("minorNumber", ctypes.c_int),
("revisionNumber", ctypes.c_int),
("buildNumber", ctypes.c_int)]
def __repr__(self):
return f'CLIF_VERSION_INFO(major={self.majorNumber},minor={self.minorNumber},rev={self.revisionNumber},build={self.buildNumber})'
dll = ctypes.CDLL('./test')
dll.CL3IF_GetVersion.argtypes = ()
dll.CL3IF_GetVersion.restype = CLIF_VERSION_INFO
print(dll.CL3IF_GetVersion())
Output:
CLIF_VERSION_INFO(major=1,minor=2,rev=3,build=4)