passing a C struct to Python and back

Alex Martelli aleax at aleax.it
Tue Jun 17 03:11:38 EDT 2003


<posted & mailed>

Kevin wrote:

> In a Python extension module, I have a struct that I need to pass to
> Python,
> then back into the extension module later for use.  Python doesn't need to
> do anything with the struct in the meantime though.
> 
> I'm trying to do it using a CObject through the following, but
> PyCObject_AsVoidPtr() returns a void*, not a struct...

Right, a void*, i.e. "a pointer to anything".  In particular, therefore,
it can be a pointer to the struct you want to pass back and forth (it
can live on the heap or in statical-lifetime memory -- not on the C stack,
obviously).

> Is there an easy way to do this?  Creating a new Python type seems like a
> big pain in the butt for something as "simple" as this.

There are many easy ways.  One is via a void*, as above.  Another is to
pass back and forth a string of bytes instead -- PyString_FromStringAndSize
to build the string object, PyString_AsString to get back the pointer to
the buffer area (as a char* to be cast) -- you shouldn't use this one if
you want your C code to modify the struct after it's been passed to Python
(strings should be immutable!).  Returning a tuple of the struct's fields
is another possibility (tuples are immutable, too), requiring more work to
pack and unpack (wasted work if Python will never need to access the
individual fields).

You could also use a "buffer object", as documented at URL
http://www.python.org/doc/current/api/bufferObjects.html -- not a very
fashionable solution nowadays but perhaps the simplest q&d fix to your
problem.  PyBuffer_FromReadWriteMemory to build (in order to use the
struct's own memory for the buffer -- this needs a struct that won't just
go away, e.g. by living on the stack;-) or PyBuffer_New if the buffer
must maintain its own memory -- and you can use the PyBufferProcs (see
http://www.python.org/doc/current/api/buffer-structs.html) to get the
pointer to the buffer's start (e.g. to memcpy the struct at start, &tc).

As I said -- plenty of choices...


Alex





More information about the Python-list mailing list