Sagar Masuti Sagar Masuti - 1 month ago 6
Python Question

Accessing the c pointer to structure in python

Is it possible to cast an

int
to a class type ?

I have the following code in C:

#include "Python.h"

#define PYTHON_FILENAME "modelparam"

void getmodelparam(long pModelParam) ;

typedef struct {
int seconds;
int nanoseconds;
} someTime;


int main ()
{
someTime *pSome ;
long a ;
printf ("Testing the python interfaces\n") ;

pSome = (someTime *) calloc(1, sizeof(someTime)) ;

pSome->seconds = 10 ;
pSome->nanoseconds = 20 ;

a = (long) pSome ;
printf ("a is %d, pSome is %d\n", a, pSome) ;

getmodelparam(a) ;

printf ("After the python call values are : %d, %d\n",pSome->seconds, pSome->nanoseconds) ;

return 0 ;

}
void getmodelparam(long pModelParam)
{
PyObject *pName ;
PyObject *pModule ;
PyObject *pDict ;
PyObject *pFunc ;
int iSize = 0 ;
char pcFunctionName[] = "modifymodelparam" ;

double dTemp1, dTemp2 ;

/* Initialize the python interpreter */
Py_Initialize() ;

/* Get Python code/module */
pName = PyUnicode_FromString(PYTHON_FILENAME);
if (NULL != pName)
{
/* Import the module equivalent to doing 'import calresidual' in python */
pModule = PyImport_Import(pName);
Py_DECREF(pName) ;
if (NULL != pModule)
{
/* Get the function and check if its callable function */
pFunc = PyObject_GetAttrString(pModule, pcFunctionName);
if (pFunc && PyCallable_Check(pFunc))
{
/* Build the input arguments */
PyObject *pResult = PyObject_CallFunction(pFunc,"i", pModelParam) ;
}
else
{
printf ("Some error with the function\n") ;
}
}
else
{
printf ("Couldnt load the module %s\n", PYTHON_FILENAME) ;
}
}
else
{
printf ("Couldnt convert the name of the module to python name\n") ;
}
/* Release the resources. */
Py_DECREF(pModule) ;
Py_DECREF(pFunc) ;
Py_DECREF(pName) ;

/*Release the interpreter */
Py_Finalize() ;
}


And in Python code:

import ctypes

class someTime(ctypes.Structure):
_fields_ = [("seconds", ctypes.c_uint),
("nanoseconds", ctypes.c_uint)]

def modifymodelparam(m):
# Not sure how to access internal elements using m ??
# How to typecast m ??
n = someTime(m)
print ('Seconds', n.seconds)


How can typecast the address passed from C to a class type in Python so that I can access those class parameters or indirectly saying accessing the structure parameters?

Answer

Well there are some mistakes in the above code.

Need to pass the pointer address as an unsigned long/int to the python module. So

void getmodelparam(long pModelParam)

//has to become

void getmodelparam(unsigned long pModelParam)

//and 

PyObject *pResult = PyObject_CallFunction(pFunc,"i", pModelParam) ;

// has to become 

PyObject *pResult = PyObject_CallFunction(pFunc,"k", pModelParam) ;

and then in the python file:

def modifymodelparam(m):
    n = ctypes.cast(m, ctypes.POINTER(someTime))
    print (n.contents.seconds)
    print (n.contents.nanoseconds)
Comments