Re: [C++-sig] (Philip Austin) PyArray_SimpleNewFromData(, PyArray_FLOAT, ) can't get c array in c extension?
Hi Philip, I did as following, but it did not work. --------------------------------c extension----------------------- PyObject * testCreatArray() { float fArray[5] = {0,1,2,3,4}; PyArrayObject * c = (PyArrayObject*)PyArray_SimpleNewFromData(1,&m,PyArray_FLOAT,fArray); return (PyObject *)c; } ---------------------------result-------------
import hello import numpy list1 = range(5); alist = hello.testCreatArray() print alist [ 4.83833291e-34 -2.52239988e-05 -2.52361860e-05 0.00000000e+00 0.00000000e+00]
-- Qinfeng(Javen) Shi Research School of Information Sciences and Engineering Australian National University Locked Bag 8001 Canberra ACT 2601
Qinfeng(Javen) Shi writes:
Hi Philip,
I did as following, but it did not work.
--------------------------------c extension----------------------- PyObject * testCreatArray() { float fArray[5] = {0,1,2,3,4}; PyArrayObject * c = (PyArrayObject*)PyArray_SimpleNewFromData(1,&m,PyArray_FLOAT,fArray); return (PyObject *)c; }
As Travis notes (on p. 187 of my copy of the numpy book), you have to guarantee that fArray lasts at least as long as the numpy array that contains it. fArray is destroyed when the function returns -- the easiest way to get around this is to let python allocate the memory and copy fArray into it: something like (untested) int nd=1; intp m=5; PyObject* c=PyArray_SimpleNew(nd, &m, PyArray_Float); then get the pointer to the data: void *arr_data = PyArray_DATA((PyArrayObject*)c); and copy memcpy(arr_data, fArray, PyArray_ITEMSIZE((PyArrayObject*) c) * m); if this copy is too expensive, boost has ways of linking the lifetime of the numpy array to a pointer to the array data (scan the boost reference for with_custodian_and_ward), so you could for example create a shared pointer to the data, skip the copy and use PyArray_SimpleNewFromData, but so far I haven't needed to do that for my applications. -- Phil
participants (2)
-
Philip Austin -
Qinfeng(Javen) Shi