使用Ctypes从Python 3传递C结构

时间:2017-08-24 11:44:03

标签: python c++ c

大家。我试图在一个使用结构作为参数的C库中调用一个函数。在C代码中(来自文件* .hh),结构如下所示:

typedef struct {
    public:
        long        nPeaks;
        long        nHot;
        float       peakResolution;         
        float       peakResolutionA;        
        float       peakDensity;             
        float       peakNpix;               
        float       peakTotal;              
        int     memoryAllocated;
        long        nPeaks_max;

        float       *peak_maxintensity;     
        float       *peak_totalintensity;   
        float       *peak_sigma;            
        float       *peak_snr;              
        float       *peak_npix;             
        float       *peak_com_x;            
        float       *peak_com_y;            
        long        *peak_com_index;        
        float       *peak_com_x_assembled;  
        float       *peak_com_y_assembled;  
        float       *peak_com_r_assembled;  
        float       *peak_com_q;            
        float       *peak_com_res;         
    } tPeakList;

我已经创建了结构的Ctypes表示:

class PeakFinderStructure(ct.Structure):
    _fields_=[('nPeaks',ct.c_long), ('nHot',ct.c_long), ('peakResolution',ct.c_float), ('peakResolutionA',ct.c_float), ('peakDensity',ct.c_float), ('peakNpix',ct.c_float), 
                ('peakTotal',ct.c_float), ('memoryAllocated',ct.c_int), ('nPeaks_max',ct.c_long), ('peak_maxintensity',ct.POINTER(ct.c_float)), ('peak_totalintensity',ct.POINTER(ct.c_float)), 
                ('peak_sigma',ct.POINTER(ct.c_float)), ('peak_snr',ct.POINTER(ct.c_float)), ('peak_npix',ct.POINTER(ct.c_float)), ('peak_com_x',ct.POINTER(ct.c_float)), ('peak_com_y',ct.POINTER(ct.c_float)), ('peak_com_index',ct.POINTER(ct.c_long)), 
                ('peak_com_x_assembled',ct.POINTER(ct.c_float)), ('peak_com_y_assembled',ct.POINTER(ct.c_float)), ('peak_com_r_assembled',ct.POINTER(ct.c_float)), ('peak_com_q',ct.POINTER(ct.c_float)), ('peak_com_res',ct.POINTER(ct.c_float))]

此结构在* .cpp中使用的函数创建。我面临的主要问题我不知道如何避免我在调用函数中添加结构指针的情况我之前无法知道,所以挑战是如何实现这个python中的fucntion 3.我写了一些代码,以至于我不知道该怎么做:

def _np_ptr(np_array):
    return ct.c_void_p(np_array.ctypes.data)

def peakfinder(peaklist, data, mask, pix_r,
                    asic_nx, asic_ny, nasics_x, nasics_y,
                    ADCthresh, hitfinderMinSNR,
                    hitfinderMinPixCount, hitfinderMaxPixCount,
                    hitfinderLocalBGRadius, outliersMask):
    '''
    C-call : int peakfinder8(tPeakList *peaklist, float *data, char *mask, float *pix_r,
                    long asic_nx, long asic_ny, long nasics_x, long nasics_y,
                    float ADCthresh, float hitfinderMinSNR,
                    long hitfinderMinPixCount, long hitfinderMaxPixCount,
                    long hitfinderLocalBGRadius, char* outliersMask)
    '''
    req = PeakFinderStructure()
    lib = ct.CDLL('')
    pfun = lib.peakfinder8
    pfun.restype = ct.c_int
    data = np.array(data, dtype=np.float32)
    pix_r = np.array(pix_r,dtype=np.float32)
    len_outliersMask = len(data)

    pfun.argtypes = (ct.POINTER(PeakFinderStructure),ct.c_void_p,ct.c_char_p,ct.c_void_p,ct.c_long,ct.c_long,ct.c_long,ct.c_long,ct.c_float,ct.c_float,ct.c_long,ct.c_long,ct.c_long,ct.c_char_p)
    k = pfun(ct.byref(req),_np_ptr(data),_np_ptr(mask),_np_ptr(pix_r),asic_nx, asic_ny, nasics_x, nasics_y,
                    ADCthresh, hitfinderMinSNR,
                    hitfinderMinPixCount, hitfinderMaxPixCount,
                    hitfinderLocalBGRadius, _np_ptr(outliersMask))
    return k, outliersMask

所以问题是如何将structer的指针放在call函数的参数中,这只会在C函数中返回。

0 个答案:

没有答案