Skip to content
Advertisement

What should I do to have multiple ctypes data types assigned to a single ctypes instance in Python?

I’m converting a C code into a Python code that uses a .dll file. The syntax for accessing the commands from the DLL is given below:

cnc_rdmacro(unsigned short FlibHndl, short number, short length, ODBM *macro);

C code Pointer to the odbm data structure is as follows:

typedef struct  odbm {
    short   datano ;    /* custom macro variable number */
    short   dummy ;     /* (not used) */
    long    mcr_val ;   /* value of custom macro variable */
    short   dec_val ;   /* number of places of decimals */
} ODBM ;

C code used to access the dll command:

  short example( short number )
{
        ODBM macro ;
        char strbuf[12] ;
        short ret ;
        ret = cnc_rdmacro( h, number, 10, &macro ) ;

The python code that I converted according to the above C code is as follows:

import ctypes
fs = ctypes.cdll.LoadLibrary(r".dll filepath")
ODBM = (ctypes.c_short * 4)() #the datatype conversion code from the above C code
ret = fs.cnc_rdmacro(libh, macro_no, 10, ctypes.byref(ODBM))

I can get the output without any errors in the above code.

The actual data structure of the ODBM has declared 4 variables of datatypes short, short, long and short which are implemented in the C code. But I had declared the ODBM data structure in python as ctypes.c_short * 4 i.e, 4 variables of short data types.

But my necessity is to declare the ODBM structure the same as in the C code and pass it to the ctypes.byref().

The ultimate solution is to include multiple data types in a single variable as a ctypes instance. Kindly help me out.

Advertisement

Answer

A ctypes.Structure should be used here:

import ctypes

class ODBM(ctypes.Structure):
    _fields_ = [("datano", ctypes.c_short),
                ("dummy", ctypes.c_short),
                ("mcr_val", ctypes.c_long),
                ("dec_val", ctypes.c_short)]

fs = ctypes.cdll.LoadLibrary(r".dll filepath")
odbm = ODBM()
ret = fs.cnc_rdmacro(libh, macro_no, 10, ctypes.byref(odbm))

print(odbm.mcr_val)
Advertisement