[英]Passing C struct to Cython and converting to Python numpy array
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 */
以下是使用
main.h
的Cythonpyx
文件
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
在該類中,編譯時出現以下錯誤:
“ Pythonout {aka struct Pythonout}”沒有名為“ n”的成員
“ Pythonout {aka struct Pythonout}”沒有名為“ x”的成員
調用對象值pnx.n
和pnx.x
。
您的代碼至少有兩個問題。
導致編譯錯誤的瑣碎問題:在C中,將結構屬性稱為px
和pn
,在Cython中,將它們稱為x
和n
。 這意味着Cython生成的代碼與C標頭不匹配。 使這些保持一致。
np.PyArray_UpdateFlags(ndarray, ndarray.flags.num | np.NPY_OWNDATA)
這告訴Numpy現在in中擁有x
的數據並負責對其進行分配。 但是,假設您具有Python代碼:
x1 = PyClassInstance.x x2 = PyClassInstance.x
現在,您有兩個Numpy數組,每個數組都相信自己擁有相同的數據,並且都將嘗試對其進行分配。 (類似地,如果您從不訪問x
則永遠不會釋放pnx.x
)您可能應該做的是讓PyClass
實例負責釋放其pnx.x
(在__dealloc__
函數中)。 然后在x
屬性中執行以下操作:
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...
現在,Numpy數組將PyClass
實例視為擁有數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.