Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

returning a python array from a C extension

1 view
Skip to first unread message

Maxwell Todd Sayles

unread,
May 27, 2002, 4:42:37 PM5/27/02
to
in python i can write:

from array import *
a = array ('B', 'some test data')

and a refers to an array object.

now i have a C extension for python that returns a PyString, and within
python i can convert it to an array

e.g.:

from array import *
from MyCExtension import *
a = array ('B', cfunction())

but this method requires an extra copy and construction from the string
to the array.

is there a way i can have cfunction return a python array? i tried
looking through the include files with the Python/C API and couldn't
find anything. any help would be appreciated.

Thanks, Maxwell Sayles

Scott Gilbert

unread,
May 27, 2002, 10:24:27 PM5/27/02
to

Yes, but since arraymodule.c doesn't have a C level API, you have to
use C to do what you would do from Python. I haven't compiled this,
and I'm being a little sloppy so you should read the docs, but it
would be something like:

/* declarations */
PyObject* globals;
PyObject* ignore;
PyObject* array;
char* pointer;
int length;

/* setup */
globals = PyDict_New();

/* import array */
ignore = PyRun_String(
"import array",
Py_file_input, globals, globals
);
Py_XDECREF(ignore);

/* create a 1234 byte array object */
array = PyRun_String(
"array.array('B', 'X')*1234",
Py_eval_input, globals, globals
);

/* use the PyBufferProcs to get a pointer to your n bytes */
PyObject_AsWriteBuffer(array, &pointer, &length);

/* build your data in your new pointer (no copy required) */
memset(pointer, 'Z', length);

/* cleanup */
Py_XDECREF(globals);

/* return put it some where... */
return array;


Also note that if your array is really big, it would be faster to
multiply in parts:

/* create a 16 meg array */
array = PyRun_String(
"array.array('B', 'X')*1024*1024*16",
Py_eval_input, globals, globals
);

Finally, it would probably be better to get the globals dict from a
real module - using the PyModule_GetDict(...) API instead of
PyDict_New(). I think the above will work today, but I suspect
someday that might not be the case...


Cheers,
-Scott

Jesper Olsen

unread,
May 28, 2002, 5:24:59 AM5/28/02
to
Maxwell Todd Sayles <say...@cpsc.ucalgary.ca> wrote in message news:<3CF29A3D...@cpsc.ucalgary.ca>...


You could also consider using the Numeric array type instead of the
build-in array type.

http://www.pfdubois.com/numpy/html2/numpy.html

If nothing else, the big advantage is that the Numeric documentation
actually describes how to do this.

Cheers
Jesper

Gary Richardson

unread,
May 28, 2002, 10:42:22 AM5/28/02
to

"Maxwell Todd Sayles" <say...@cpsc.ucalgary.ca> wrote in message
news:3CF29A3D...@cpsc.ucalgary.ca...

I've written a wrapper using CXX that passes Python array information
to/from some C functions (FFTW). I'll be glad to send you some
example Python code and the C wrapper if that would be of interest.

Gary Richardson

0 new messages