Python and C, arrays
Michael P. Reilly
arcege at shore.net
Tue Jun 15 14:16:55 EDT 1999
John Fisher <jfisher at are.berkeley.edu> wrote:
: Hey folks,
: I've run into a problem with a module I'm writing in C. Basically, I
: need to be able to convert Python tuples or lists (it's unimportant
: which) into C arrays. I know at compile-time the type of the array (and
: that the tuple or list will be homogeneous, and of compatible type), but
: I don't know the size.
: I then need to find a way to take a C array and stuff it back into a
: Python tuple or list. I have some ideas involving using "stack-like"
: lists or tuples in Python, with a "pop" function which I could call from
: C, repeated in a loop to get everything. But this seems overly complex,
: and indeed like it has the potential to become truly hideous.
: I would imagine these two tasks are actually quite common. Is there
: some simpler way to do either? Dare I hope that PyArg_ParseTuple and
: Py_BuildValue can do it?
Use the Abstract Layer's PySequence_*() functions in the C API
(http://www.python.org/doc/current/api/sequence.html)
PyObject_Length() will give you the number of elements in a tuple or
list. And from the other direction (if you do not know the size of the
array), use (sizeof(array)/sizeof(array[0])).
Here are some specific converters for you (from a Python sequence to a
C array of PyObject* and back).
int convert_PySeq2C(seq, array)
PyObject *seq;
PyObject ***array;
{ int i, n;
PyObject *tmp;
n = PyObject_Length(seq);
*array = (PyObject *)malloc(n * sizeof(PyObject *));
for (i = 0; i < n; i++) {
tmp = PySequence_GetItem(seq, i); /* not a 'borrowed' reference */
if (tmp == NULL) {
free(*array);
*array = NULL;
return -1; /* exception set already */
}
Py_INCREF(tmp);
(*array)[i] = tmp;
}
return n;
}
Converting back to Python is a little simplier:
PyObject *convert_PySeq2C(array, n)
PyObject *array[];
int n;
{ int i;
PyObject *result;
result = PyTuple_New(n);
if (result != NULL) {
for (i=0; i < n; i++)
PyTuple_SetItem(result, i, array[i]); /* increments the ref count */
}
return result;
}
There will be other, more efficient, means that would be tailored to
your app.
-Arcege
More information about the Python-list
mailing list