2012-04-08 19 views
10

में रैपिंग सी फ़ंक्शन मैं कुछ एनम्पी एरे में हेरफेर करने के लिए पाइथन से अपना सी फ़ंक्शन कॉल करना चाहता हूं। समारोह इस तरह है:साइथन और न्यूमपी

void c_func(int *in_array, int n, int *out_array); 

जहां परिणाम out_array, जिसका आकार पहले से मैं जानता हूँ कि में आपूर्ति की जाती है (नहीं मेरी समारोह, वास्तव में)। मैं में करने की कोशिश इसी .pyx एक NumPy सरणी से फ़ंक्शन का इनपुट गुजरती हैं, और एक NumPy सरणी में परिणाम स्टोर कर के लिए, निम्न फ़ाइल क्रम में:

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):  
    n = len(in_array) 
    out_array = np.zeros((512,), dtype = np.int32) 
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data) 
    return out_array 

लेकिन मैं "Python objects cannot be cast to pointers of primitive types" मिल आउटपुट असाइनमेंट के लिए त्रुटि। मैं इसे कैसे पूर्ण करूं?

(अगर मैं अपेक्षा करते हैं कि अजगर फोन करने वाले उचित उत्पादन सरणी आबंटित करता है, तो मैं

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array, np.ndarray[np.int32_t, ndim=1] out_array): 
    n = len(in_array) 
    mymodule.cfunc(<int *> in_array.data, n, <int*> out_array.data) 

कर सकते हैं लेकिन मैं एक तरीका है कि फोन करने वाले को उचित रूप से पूर्व आवंटित करने के लिए नहीं है में यह कर सकते हैं आकार का आउटपुट सरणी?

+1

आप 'cdef np.ndarray' से पहले' out_array' assignement जोड़ने उपलब्ध कराने का प्रयास किया? – Simon

+0

यह काम करता है, धन्यवाद !!! – Peter

उत्तर

5

आप out_array assignement से पहले cdef np.ndarray जोड़ना चाहिए:

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):  
    cdef np.ndarray out_array = np.zeros((512,), dtype = np.int32) 
    n = len(in_array) 
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data) 
    return out_array 
0

यहां एक उदाहरण है कि सी/सी ++ में सीटीपीएस के माध्यम से लिखित कोड का उपयोग करके न्यूमपी एरे का उपयोग कैसे करें। मैंने सी में एक छोटा सा फ़ंक्शन लिखा, पहले सरणी से संख्याओं का वर्ग लेना और परिणाम लिखना एक दूसरी सरणी। तत्वों की संख्या तीसरे पैरामीटर द्वारा दी जाती है। यह कोड साझा ऑब्जेक्ट के रूप में संकलित किया गया है।

squares.c squares.so को संकलित:

void square(double* pin, double* pout, int n) { 
    for (int i=0; i<n; ++i) { 
     pout[i] = pin[i] * pin[i]; 
    } 
} 

अजगर में, आप बस पुस्तकालय ctypes का उपयोग कर लोड और फ़ंक्शन को कॉल करें। सरणी पॉइंटर्स NumPy ctypes इंटरफ़ेस से प्राप्त किए जाते हैं।

import numpy as np 
import ctypes 

n = 5 
a = np.arange(n, dtype=np.double) 
b = np.zeros(n, dtype=np.double) 

square = ctypes.cdll.LoadLibrary("./square.so") 

aptr = a.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) 
bptr = b.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) 
square.square(aptr, bptr, n) 

print b 

यह किसी भी सी पुस्तकालय के लिए काम करेंगे, तो आप सिर्फ जानना चाहता है जो तर्क प्रकार, पारित संभवतः ctypes का उपयोग कर अजगर में सी structs पुनर्निर्माण करना है।

+2

मुझे लगता है कि ओपी सीटीपी के बजाए साइथन का उपयोग करना चाहता है – Simon

संबंधित मुद्दे