[capi-sig] Reference counts and dictionary creadtion
Stefan Behnel
python_capi at behnel.de
Tue Dec 29 23:25:23 CET 2009
Dan Colesworthy, 29.12.2009 21:38:
> I am attempting to write a python extension in C to "glue" the ASIO SDK
> to python 2.5.4. However I am really confused about reference counts.
You might want to take a look into Cython, a Python-like language that is
well suited for writing very fast C library wrappers. Besides many other
features, it will do all the reference counting for you and generates code
that works in Python 2 and Python 3.
> Below is a code snippet that "seems" to work, however I suspect that
> some of the object reference counts have been incremented too many
> times.
>
>
> static PyObject *
>
> getAsioInfo(PyObject *self, PyObject *args) {
>
> PyObject *dict = Py_None;
>
> if (loadAsioDriver (ASIO_DRIVER_NAME)) {
>
> if (ASIOInit (&asioDriverInfo.driverInfo) == ASE_OK){
>
> dict = PyDict_New();
>
> PyDict_SetItem(dict,
>
> PyString_FromString("asioVersion"),
Yes, this doesn't work. PyDict_SetItem() doesn't steal the reference, so
you end up with a dangling reference to the just created string. Same for
the other objects created below:
> PyInt_FromLong(asioDriverInfo.driverInfo.asioVersion) );
>
> PyDict_SetItem(dict,
>
> PyString_FromString("driverName"),
>
>
> PyString_FromString(asioDriverInfo.driverInfo.name) );
You need to assign each object to a variable, call SetItem() on it, and
then Py_DECREF() it afterwards.
Note that there is also a special function PyDict_SetItemString() that
accepts a char* as key and creates the Python string object internally.
Also note that the PyString_*() functions are likely not what you want to
use in Python 3.
Stefan
More information about the capi-sig
mailing list