Creating custom types from C code

Eric Frederich eric.frederich at gmail.com
Fri Dec 17 17:58:54 EST 2010


Hello,

I have an extension module for a 3rd party library in which I am
wrapping some structures.
My initial attempt worked okay on Windows but failed on Linux.
I was doing it in two parts.
The first part on the C side of things I was turning the entire
structure into a char array.
The second part in Python code I would unpack the structure.

Anyway, I decided I should be doing things a little cleaner so I read
up on "Defining New Types"
http://docs.python.org/extending/newtypes.html

I got it to work but I'm not sure how to create these new objects from C.

My setup is almost exactly like the example on that page except
instead of 2 strings and an integer I have 5 unsigned ints.

I do not expect to ever be creating these objects in Python.  They
will only be created as return values from my wrapper functions to the
3rd party library.
I could return a tuple from those functions but I want to use dot
notation (e.g. somestruct.var1).

So, question number 1:
    Is defining my own type like that overkill just to have an object
to access using dots?
    I'll never create those objects from Python.
    Is there a shortcut to creating objects and setting attributes
from within C?

In any case, I was able to create my own custom object from C code like so...

    PyObject *foo(SomeCStruct bar){
        PyObject *ret;
        ret = _PyObject_New(&mymodule_SomeStructType);
        PyObject_SetAttrString(ret, "var1" , Py_BuildValue("I", bar.var1 ));
        PyObject_SetAttrString(ret, "var2" , Py_BuildValue("I", bar.var2 ));
        PyObject_SetAttrString(ret, "var3" , Py_BuildValue("I", bar.var3 ));
        PyObject_SetAttrString(ret, "var4" , Py_BuildValue("I", bar.var4 ));
        PyObject_SetAttrString(ret, "var5" , Py_BuildValue("I", bar.var5 ));
        return ret;
    }

When using _PyObject_New I notice that neither my new or init function
are ever called.
I verified that they are getting called when creating the object from
Python (which I would never do anyway).

Question number 2:
    Do I need to be calling PyObject_SetAttrString or is there a way
to set the unsigned ints on the structure direcly?
    It seems overkill to create a Python object for an unsigned int
just to set it as an attribute on a custom defined type.

Question number 3:
    In the above code, is there a memory leak?  Should I be
Py_DECREF'ing the return value from Py_BuildValue after I'm done using
it.



More information about the Python-list mailing list