ifndef MAIN_H
define MAIN_H
ifdef __cplusplus
extern "C" {
endif
typedef struct Pythonout{
int pn;
double *px;
}Pythonout;
struct Pythonout l1tf_main(char *ifile_y, double lambda, int rflag);
ifdef __cplusplus
}
endif
endif /* MAIN_H */
Following is the Cython
pyx
file usingmain.h
cimport numpy as np
cdef extern from "main.h":
ctypedef struct Pythonout:
int n
double *x
cdef Pythonout l1tf_main(char *ifile_y
,double lambdaval,
int rflag);
cdef class Pyclass:
cdef Pythonout pnx
def __cinit__(self, char *pfilename,
lambdaval, rflag):
self.pnx = l1tf_main(pfilename,
lambdaval, rflag)
@property
def n(self):
return self.pnx.n
@property
def x(self):
cdef np.npy_float64 shape[1]
shape[0] = <np.npy_intp> self.pnx.n
ndarray =
np.PyArray_SimpleNewFromData(1,
&(self.pnx.n),np.NPY_FLOAT64,
<void *> self.pnx.x)
np.PyArray_UpdateFlags(ndarray,
ndarray.flags.num
| np.NPY_OWNDATA)
return ndarray
cpdef filtered_trend(char *pfilename, double
lambdaval, int rflag):
pnx = Pyclass(pfilename, lambdaval, rflag)
return pnx.x
In the class I am getting the following error while compiling:
'Pythonout {aka struct Pythonout}' has no member named 'n'
'Pythonout {aka struct Pythonout}' has no member named 'x'
When calling the object value pnx.n
and pnx.x
.
There's at least two issues with your code.
The trivial issue causing the compilation errors: in C you call the struct attributes px
and pn
, while in Cython you call them x
and n
. This means that the code Cython generates does not match the C header. Make these consistent.
np.PyArray_UpdateFlags(ndarray, ndarray.flags.num | np.NPY_OWNDATA)
This tells Numpy that in now owns the data in x
and is responsible for deallocating it. However suppose you have the Python code:
x1 = PyClassInstance.x x2 = PyClassInstance.x
You now have two Numpy arrays that each believe the own the same data and will both try to deallocate it. (Similarly if you never access x
then pnx.x
is never deallocated) What you should probably do is have the PyClass
instance be responsible for deallocating its pnx.x
(in a __dealloc__
function). Then in your x
property do:
ndarray = PyArray_SimpleNewFromData(...) Py_INCREF(self) # SetBaseObject doesn't do this so you must do it manually PyArray_SetBaseObject(ndarray, self) # check return value for errors...
Now the Numpy array treats the PyClass
instance as owning the data.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.