Search code examples
pythoncpython-c-apipython-embedding

Parsing Python Structure as PyObject


I'm returning object of following structure from a python function

class Bus(Structure):
    _fields_ = [ ("a", c_int), 
                 ("b", c_char), 
                 ("c", c_float), 
                 ("d", c_double), 
                 ("e", c_char_p) 
               ]

def GetBus(  *args, **kwargs ):
    Signal = cast(c_char_p(kwargs['Bus']), POINTER(Bus )).contents
    ## Logic that updates Signal
    return Signal

In my C code, I want update my C struct bus, by parsing the pValue, obtained from :

  Bus bus ;
  python_Bus = Py_BuildValue("s#",  (char* )&bus,  sizeof(Bus)) ;
  PyDict_SetItemString( pDict,"Bus", python_Bus ) ;

  PyObject* pValue = PyObject_Call(pFunc, pArgs,pDict) ;

How to I parse pValue ?

Is there's any Py???_???(pvalue, ???) ; ? or How do I convert it to char* and do a memcpy in my C code (if that's a way) ?


I also tried creating a new Python Type, but looks like it all boiled down to Py_BuildValue in my "getter" function, and I don't want to have several "setters" for each element.

Using Python2.7


Solution

  • Assuming you're using ctypes.Structure, you could use the implementation of Buffer interface.

    Try something like:

    Py_buffer view = { 0 };
    PyObject_GetBuffer(pvalue, &view, PyBUF_SIMPLE);
    // use view.buf, which is of void*
    PyBuffer_Release(&view);
    

    You might want to add some error handling to be sure of getting the proper data.