2011-04-28 11 views
8

की एक सरणी लौट रहा है, मुझे पता है, कुछ समस्याओं को हल करने के कई तरीके हैं। लेकिन यहाँ मैं जानता हूँ कि जो जिस तरह से मैं इसे करना चाहते हैं, लेकिन मैं इसे अजगर और बड़ा घूँट के साथ काम करने में असमर्थ हूँ ...स्विग, युगल

मैं एक सी समारोह है, जो मुझे डबल मूल्यों की एक सरणी देता है:

double *my(int x) 
{ 
    double a,b,*buf; 
    buf = malloc (x * sizeof(double)); 
    a=3.14; 
    b=2.7; 
    buf[0]=a; 
    buf[1]=b; 
    return buf; 
} 

यहां, मैं निश्चित रूप से सरणी को वापसी मूल्य के रूप में रखना चाहता हूं। नहीं, जैसा कि कई उदाहरणों में एक 'शून्य' फ़ंक्शन है, जो एक इनपुट सरणी में लिखता है। मैं हमेशा s.th. मिल -

>>> import example 
>>> print example.my(7) 
[3.14,2.7] 

जो कुछ भी मैं, मैं कुछ वैचारिक समस्याओं यहाँ है: अब, मैं एक बड़ा घूँट-अजगर आवरण है, जो के रूप में इस्तेमाल किया जा सकता प्राप्त करना चाहते हैं <Swig Object of type 'double *' at 0xFABCABA12>

की तरह मैं अपने swg फाइल में कुछ typemaps को परिभाषित करने की कोशिश की:

%typemap(out) double [ANY] { 
    int i; 
    $result = PyList_New($1_dim0); 
    for (i = 0; i < $1_dim0; i++) { 
    PyObject *o = PyFloat_FromDouble((double) $1[i]); 
    PyList_SetItem($result,i,o); 
    } 
} 

लेकिन फिर भी मैं अपने परिणामों बाहर निकलने के लिए के रूप में आवश्यक असमर्थ हूँ। क्या इस कार्य को प्राप्त करने के लिए किसी के पास एक साधारण कोड-उदाहरण है?

+0

अप्स, हाँ, यह मेरे सामने मौजूद वास्तविक कोड का एक सुपर-छोटा सबसेट है। गलतफहमी के लिए खेद है। – user701370

उत्तर

-3

मैं नहीं जानता कि आप कितना जानते हैं सी - तो क्षमा याचना करता है, तो मैं तुम्हें यहाँ अंडे चूसना करने के लिए शिक्षण हूँ ...

सादे OLE सी में कोई सरणी वर्ग एक सरणी हमेशा एक है नहीं है स्मृति के एक टुकड़े के लिए सूचक, खुद में एक "चीज" नहीं है और इसलिए स्वयं ही मुद्रित नहीं किया जा सकता है।

इस मामले में - आपका "buf" प्रकार "डबल *" है। AFAICRem, यदि आप "स्मृति द्वारा इंगित स्मृति" पर संग्रहीत वास्तविक मानों को मुद्रित करना चाहते हैं, तो आपको प्रत्येक को उदाहरण देना होगा (उदाहरण के लिए छद्म कोड में): i = 0 से buflength print buf [i]

+1

गलत: [सी-एफएचक] (http://c-faq.com/) की धारा 6 पढ़ें। Arrays पॉइंटर्स नहीं हैं; पॉइंटर्स सरणी नहीं हैं। – pmg

+0

हां, वे समान नहीं हैं ... यह मेरा मुद्दा नहीं था। मुद्दा यह है कि सी में, आप नहीं कर सकते, "my_array.length" सी में, एक सरणी यह ​​नहीं जानता कि यह कितना बड़ा है (जो कई ओओ भाषाओं में करता है), और आप समझदारी से प्रिंट नहीं कर सकते ऊपर वर्णित तरीके से बाहर। आपको खुद को काम करना है। –

1

आप शायद carray.i:

% में "carrays.i" % array_class (int, intArray) शामिल है;

http://www.swig.org/Doc2.0/Python.html#Python_nn48

+1

मुझे नहीं लगता कि ये आउटपुट के लिए कैसे काम कर सकते हैं (इनपुट केस दस्तावेज़ीकरण से बहुत स्पष्ट है)। क्या आप एक उदाहरण दे सकते हैं? – kynan

4

पहली समस्या है कि आपके typemap से मेल नहीं खाता, तो आप एक %typemap(out) double * { ... } अपने कार्य को दोगुना करने के लिए सूचक रिटर्न और एक डबल सरणी नहीं के बाद से की आवश्यकता होगी है।

अपनी सूची (यानी एक पूर्णांक शाब्दिक) उदाहरण आप दे दी है (जो मुझे लगता है कि आप क्या चाहते नहीं है) के रूप में निश्चित आकार का है, तो आप बस typemap को बदल सकता है के रूप में मैं ऊपर दे दी है और निश्चित आकार के लिए विदेशी मुद्रा $1_dim0

अन्यथा आपकी समस्या यह है कि आपके संभवतः आपके पैरामीटर int x के मान को नहीं जान सकते हैं। आप एक ऐसी संरचना वापस कर सकते हैं जिसमें पॉइंटर और आकार दोनों हों। फिर आप इसे एक सूची में बदलने के लिए एक टाइपमैप को आसानी से परिभाषित कर सकते हैं (या एक NumPy सरणी, Wrap C struct with array member for access in python: SWIG? cython? ctypes? पर भी मेरी प्रतिक्रिया देखें)।

संयोग से सी में एक निश्चित आकार की सरणी वापस करना संभव नहीं है (यह उत्तर भी देखें: Declaring a C function to return an array), इसलिए %typemap(out) double [ANY] { ... } कभी मेल नहीं खा सकता है।

3

मुझे इसी तरह की समस्या का सामना करना पड़ा और इसे निम्नलिखित तरीके से हल किया गया।

// example.i 

%module example 

%include "carrays.i" 
%array_class(float, floatArray); 

float * FloatArray(int N); 

float SumFloats(float * f); 

 

# ipython 

> a = example.floatArray(23) # array generated by swig's class constructor 

> a 

<example.floatArray; proxy of <Swig Object of type 'floatArray *' at 0x2e74180> > 

> a[0] 

-2.6762280573445764e-37 # unfortunately it is created uninitialized.. 

> b = example.FloatArray(23) # array generated by function 

> b 

<Swig Object of type 'float *' at 0x2e6ad80> 

> b[0] 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
# ..... 
TypeError: 'SwigPyObject' object is not subscriptable 

> #But there is a way to access b!! 

> p = example.floatArray_frompointer(b) # i found this function by example. and twice tab 

> p 

<example.floatArray; proxy of <Swig Object of type 'floatArray *' at 0x2e66750> > 

> p[0] 

0.0 

> p[0] = 42 

> p[0] 

42.0 

सौभाग्य से, इन प्रकार के (नाव *, floatArray *, और floatArray * की प्रॉक्सी) के सभी सफलतापूर्वक सेल्सियस तक ++ समारोह (जैसे SumFloats के रूप में) पारित किया जा सकता है।

1

आप अपने अजगर कोड में numpy अजगर मॉड्यूल में खींच कोई आपत्ति नहीं है, तो आप निम्न कर सकते हैं:

बड़ा घूँट इंटरफ़ेस फ़ाइल में:

%{ 
#define SWIG_FILE_WITH_INIT 
%} 
%include "numpy.i" 
%init %{ 
import_array(); 
%} 

%apply(float ARGOUT_ARRAY1[ANY]) {(float outarray1d[9])}; 
void rf(float outarray1d[9]); 

केवल पिछले दो लाइनें हैं इस उदाहरण के लिए विशिष्ट, पहली सामग्री numpy.i के लिए डिफ़ॉल्ट है (numpy.i दस्तावेज कहीं और देखें: http://docs.scipy.org/doc/numpy/reference/swig.interface-file.html)।

सी फ़ाइल में (भी मैं फ़ाइल में inlined जा सकता है):

void rf(float outarray1d[9]) { 
    float _internal_rf[9]; 
    /* ... */ 
    memcpy(outarray1d, _internal_rf, 9*sizeof(float)); 
} 
फिर

आप एक समारोह है जो आप अब के रूप में

import mymodule 
a = mymodule.rf() 
# a is a numpy array of float32's, with len 9 

अजगर से कॉल कर सकते हैं, यदि आप डॉन अपने पायथन परियोजना में numpy मॉड्यूल में खींचने के लिए मजबूर होना नहीं चाहते हैं, तो मेरा सुझाव है कि आप numpy.i जांचें कि वे% टाइपमैप चाल कैसे करते हैं - जैसा कि मैं इसे समझता हूं, यह SWIG टाइपमैप के साथ किया जाता है और स्वाभाविक रूप से बंधे नहीं numpy करने के लिए - वापसी मूल्य के रूप में tuples या सूचियों के साथ एक ही चाल करने के लिए संभव होना चाहिए।

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