
Dan Colesworthy wrote:
Hello,
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. 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"),
PyInt_FromLong(asioDriverInfo.driverInfo.asioVersion) );
PyDict_SetItem(dict, PyString_FromString("driverName"),
PyString_FromString(asioDriverInfo.driverInfo.name) );
return dict; }
}
return Null;
}
As nearly as I can tell from the Python source code, PyDict_SetItem will do a Py_INCREF on both the key and value parameters. However, it looks as if PyInt_FromLong will incref the object it is returning - at least if it is a "small value".
Object constructors will always return objects with a refcount of 1.
When adding a key, value pair to a dictionary using PyDict_SetItem() the function will take care of adjusting the refcounts.
After the call, you still own the objects key and value, so you have to decref them if you no longer need them.
Am I on the right track here? Or am I better off doing something like:
PyObject *str, *lng; str = PyString_FromString("asioVersion"); lng = PyInt_FromLong(asioDriverInfo.driverInfo.asioVersion)
);
PyDict_SetItem(dict, str, lng);
Py_DECREF(str);
Py_DECREF(lng);
See above. The second approach is likely what you need.
BTW: PyDict_SetItemString() is usually a better approach to filling dictionaries that use often used keys. It interns the key string for you, making subsequent lookups faster.
OTOH, if you plan to port to Python 3.x, you will likely want to use Unicode objects as keys.
-- Marc-Andre Lemburg eGenix.com
Professional Python Services directly from the Source (#1, Dec 30 2009)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::: Try our new mxODBC.Connect Python Database Interface for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/