cty+

2013-02-15 9 views
15

का उपयोग कर सी ++ फ़ंक्शन से पायथन तक सरणी कैसे वापस करें I Python में C++ फ़ंक्शन को लागू करने के लिए ctypes का उपयोग कर रहा हूं। सी ++ फ़ंक्शन को एक पॉइंटर को सरणी में वापस करना चाहिए। दुर्भाग्य से मुझे पता नहीं चला है, पायथन में सरणी का उपयोग कैसे करें। मैंने numpy.frombuffer की कोशिश की, लेकिन यह सफल नहीं था। यह सिर्फ मनमानी संख्याओं की एक सरणी लौटा दी। जाहिर है मैंने इसे सही ढंग से उपयोग नहीं किया।cty+

function.cpp की सामग्री::

extern "C" int* function(){ 
int* information = new int[10]; 
for(int k=0;k<10;k++){ 
    information[k] = k; 
} 
return information; 
} 

wrapper.py की सामग्री:

import ctypes 
import numpy as np 

output = ctypes.CDLL('./library.so').function() 

ArrayType = ctypes.c_double*10 
array_pointer = ctypes.cast(output, ctypes.POINTER(ArrayType)) 
print np.frombuffer(array_pointer.contents) 

सी ++ फ़ाइल मैं उपयोग कर रहा हूँ संकलन करने के लिए यहाँ आकार 10 की एक सरणी के साथ एक सरल उदाहरण है :

g++ -c -fPIC function.cpp -o function.o 
g++ -shared -Wl,-soname,library.so -o library.so function.o 

क्या आपके पास कोई सुझाव है कि मुझे पायथन में सरणी मानों तक पहुंचने के लिए क्या करना है?

+0

बेशक मैं c_double और POINTER जैसे कुछ विशिष्ट ctypes कार्यों को आयात करना भूल गया। मैं बस उन्हें यहां जोड़ना भूल गया। – dolby

उत्तर

12

function.cpp एक int सरणी देता है, जबकि wrapper.py उन्हें युगल के रूप में समझने की कोशिश करता है। ArrayType से ctypes.c_int * 10 बदलें और इसे काम करना चाहिए।


यह शायद बस अपने आप को frombuffer के बजाय np.ctypeslib उपयोग करने के लिए आसान है। आपका अजगर कोड कुछ मामूली संशोधनों के बाद काम करेंगे यह कुछ की तरह

import ctypes 
from numpy.ctypeslib import ndpointer 

lib = ctypes.CDLL('./library.so') 
lib.function.restype = ndpointer(dtype=ctypes.c_int, shape=(10,)) 

res = lib.function() 
+0

मैंने भी c_int आयात किया और c_double को प्रतिस्थापित किया लेकिन पाइथन प्रिंट अब केवल 5 तत्वों की एक सरणी है और मान अभी भी गलत हैं। यह अजीब है। – dolby

+0

बढ़िया, बहुत बहुत धन्यवाद! यह अब काम करता है। पायथन सिर्फ मुझे चेतावनी देता है "[...] रनटाइम चेतावनी: अमान्य पीईपी 3118 प्रारूप स्ट्रिंग: '<पी' [...]" लेकिन [इस चर्चा] के अनुसार (http://stackoverflow.com/questions/4964101/ पेप -3118-चेतावनी-कब-उपयोग-ctypes-array-as-numpy-array) यह कोई समस्या नहीं है। – dolby

+0

यहां कुछ परेशानी है ... इसके साथ होने पर स्मृति को आप कैसे हटा देंगे? – XapaJIaMnu

17

दिखना चाहिए:

  1. निकालें numpy से संबंधित कोड और ctypes.cast कॉल:

    import ctypes 
    
    f = ctypes.CDLL('./library.so').function 
    f.restype = ctypes.POINTER(ctypes.c_int * 10) 
    print [i for i in f().contents] # output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
    

    असल में वहाँ दो परिवर्तन कर रहे हैं क्योंकि हमें उनकी आवश्यकता नहीं है।

  2. वापसी प्रकार को ctypes.POINTER(ctypes.c_int * 10) पर निर्दिष्ट करें।

    डिफ़ॉल्ट रूप से विदेशी कार्यों को सी int प्रकार वापस करने के लिए माना जाता है, इसलिए हमें इसे वांछित सूचक प्रकार में बदलने की आवश्यकता है।

Btw, पायथन कोड के लिए सी कोड से एक new एड सरणी लौटने अनुचित लगता है। स्मृति कब और कब मुक्त करेगा? पायथन कोड में सरणी बनाना और उन्हें सी कोड में पास करना बेहतर है। इस तरह यह स्पष्ट है कि पायथन कोड सरणी का मालिक है और अपनी रिक्त स्थान बनाने और पुनः दावा करने की ज़िम्मेदारी लेता है।

+2

क्या आप इंगित कर सकते हैं कि हम पाइथन में ऐसी सरणी कैसे बनाएंगे और सी के पॉइंटर को पास करेंगे? – shahensha

+0

@ शेंगेषा मैं int/float arrays के लिए क्या करता हूं, numpy arrays का उपयोग करता है, और एम्बेडेड ctypes इंटरफ़ेस ('data_as') – Adversus

+0

यहां कुछ necromancery ... आप इसके साथ होने पर स्मृति को कैसे हटाएंगे? – XapaJIaMnu