簡體   English   中英

將C結構傳遞給Cython並轉換為Python numpy數組

[英]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的Cython pyx文件

.pyx

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.npnx.x

您的代碼至少有兩個問題。

  1. 導致編譯錯誤的瑣碎問題:在C中,將結構屬性稱為pxpn ,在Cython中,將它們稱為xn 這意味着Cython生成的代碼與C標頭不匹配。 使這些保持一致。

  2.  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM