En Sat, 27 Dec 2008 22:54:52 -0200, Daniel Fetchinson
<fetchin...@googlemail.com> escribió:
This is the function I have, the corresponding python function will
take two equal length lists of integers and the C function will
compute their sum and return the result as a python tuple.
static PyObject *func( PyObject * self, PyObject * args )
{
int j, N;
int * src1, * src2;
PyObject *list1, *list2;
list1 = PyTuple_GetItem( args, 0 );
N = PyList_Size( list1 );
src1 = ( int * ) malloc( N * sizeof( int ) );
for( j = 0; j < N; j++ )
{
src1[j] = (int)PyInt_AsLong( PyList_GetItem( list1, j ) );
}
list2 = PyTuple_GetItem( args, 1 );
N = PyList_Size( list2 );
src2 = ( int * ) malloc( N * sizeof( int ) );
for( j = 0; j < N; j++ )
{
src2[j] = (int)PyInt_AsLong( PyList_GetItem( list2, j ) );
}
PyObject * tuple;
tuple = PyTuple_New( N );
for( j = 0; j < N; j++ )
{
PyTuple_SetItem( tuple, j, PyInt_FromLong( (long)( src1[j] +
src2[j] ) ) );
}
free( src1 );
free( src2 );
return tuple;
}
As others already said, using a Numpy array or an array.array object would
be more efficient (and even easier - the C code gets a pointer to an array
of integers, as usual).
Do I have to free the memory occupied by the python objects list1 and
list2?
No. Usually you don't do that for any Python object - just
increment/decrement its reference count (using Py_INCREF/Py_DECREF).
Do I have to do any refcounting for list1, list2, tuple?
In this case list1 and list2 come from PyTuple_GetItem; the docs say it
returns a "borrowed reference" (that is, the function doesn't increment
the refcount itself). So you don't have to decrement it yourself (and it
isn't necesary to increment it in the first place, because the "args"
tuple holds a reference, so the object can't disappear until the function
exits, at least)
Any comment on the above code will be very appreciated! If I'm pushed
in the right direction I'm a fast learner but the beginning steps are
always hard :)
You MUST check EVERY function call for errors!
And check the argument's type (how do you know it is a list?). Once you
are sure the first parameter *is* a list, you may use the "macro" version
of several functions, like PyList_GET_SIZE and PyList_GET_ITEM.
You should check that both lists have the same length too.
And you should check that elements are integers, or convertible to
integers (in case of error, PyInt_AsLong returns -1 and PyErr_Occurred()
is true)
To fill the resulting tuple, use PyTuple_SET_ITEM instead. BTW, why return
a tuple and not a list?
--
Gabriel Genellina
--
http://mail.python.org/mailman/listinfo/python-list