C structure in the Python extension

Craig Ringer craig at postnewspapers.com.au
Mon Jan 10 18:17:51 EST 2005


Dave win wrote:

>Howdy:
>	When I was writting interface functions of the extending python,      I
>meet a question. As I using the  "PyArg_ParseTuple(args,arg_type,...)"
>function call, if I wanna use the personal defined argument, such as the
>C structure which I made. How to make it?
>
>static PyObject* Call_V_ABSUB(PyObject *self, PyObject* args){
>          myStruct FU;
>          myStruct result;
>          if(!PyArg_ParseTuple(args,"O&",&FU)) return NULL;
>				     ^^^^^^^
>				     How to modify here???
>          V_ABSUB(FU);
>
>          return Py_BuildValue("i",result);
>}
>  
>
You can't, really. Python code can't work with C structs directly, so it
can't pass you one. I have used one utterly hideous hack to do this when
prototyping code in the past, but that was before I knew about
PyCObject. PyCObject is also pretty evil if abused, but nowhere NEAR on
the scale of what I was doing. Can you say passing pointers around as
Python longs? Can't bring yourself to say it? Don't blame you. My only
defense was that it was quick hack prototype code, and that the Python/C
API for making classes is too painful to use when quickly prototyping
things.

To do what you want, you could encapsulate a pointer to the struct in a
PyCObject, then pass that around. Your Python code will just see a
PyCObject with no attributes or methods; it can't do anything to it
except pass it to other Python code (and delete it, but that'll result
in a memory leak if the PyCObject holds the only pointer to the struct).
Your C code can extract the pointer to the struct and work with that. DO
NOT do this if the Python code just deleting the PyCObject could ever
discard the last pointer to the struct, as you'll leak the struct.

A much BETTER option is probably to rewrite myStruct to be a Python type
("class") implemented in C, and provide it with both a C and Python API.
This isn't too hard, though the Python/C API does make creating types a
bit cumbersome. (Most of this seems to be because you're playing
pretend-we-have-objects in C, rather than issues specific to the
Python/C API).

--
Craig Ringer





More information about the Python-list mailing list