विचार जो आपने [ANY]
के साथ प्रयास किया है, कई कारणों से काम नहीं करेगा। मुख्य रूप से ANY
का उपयोग टाइपमैप में किया जा सकता है ताकि एक ही टाइपमैप को अलग-अलग आकार के सरणी के साथ काम करने की अनुमति मिल सके, जो कि आपके पास नहीं है।
सी के लिए सिंटैक्स या तो वहां क्वियर नहीं है। आप नहीं लिख सकते हैं:
int[4] bar() {
static int data[4];
return data;
}
या:
int bar()[4] {
static int data[4];
return data;
}
मानक निकटतम आप प्राप्त कर सकते हैं सी में है:
int (*bar())[4] {
static int data[4] = {1,2,3,4};
return &data;
}
लेकिन वह वास्तव में किसी भी रैप करने के लिए आसान नहीं है। द्वारा
Python 3.2.3 (default, May 3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> arr = test.fooArray.frompointer(test.bar())
>>> arr
<test.fooArray; proxy of <Swig Object of type 'fooArray *' at 0xb6f332a8> >
>>> arr[0]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f33038> >
>>> arr[1]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f33380> >
>>> arr[2]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f33398> >
>>> arr[3]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f330c8> >
>>>
हम एक कदम बेहतर हालांकि (संभवतः) जा सकते हैं:
हालांकि, सरल उपाय, %array_class
का उपयोग कर काम करने के लिए उदाहरण के लिए बनाया जा सकता है:
%module test
%inline %{
struct foo {
int member;
};
struct foo *bar() {
struct foo *arr = malloc(sizeof(struct foo) * 4);
for (int i = 0; i < 4; ++i)
arr[i].member = i;
return arr;
}
%}
%include <carrays.i>
%array_class(struct foo, fooArray);
यह सुविधा देता है मुझे करना bar()
से पहले निम्नलिखित जोड़कर पॉइंटर को सरणी प्रकार में जोड़ने के लिए कोड को इंजेक्शन करना SWIG:
%pythonappend bar() %{
# Wrap it automatically
val = fooArray.frompointer(val)
%}
तो अब यह पसंद का उपयोग कर सकते हैं:
Python 3.2.3 (default, May 3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> test.bar()[1].member
1
>>> arr = test.bar()
>>> arr[3].member
3
आप स्मृति स्वामित्व के बारे में सावधान रहने की जरूरत है। इन उदाहरणों में अब तक स्मृति लीक हो गई है। एसडब्ल्यूआईजी को यह बताने के लिए आप %newobject
का उपयोग कर सकते हैं कि मेमोरी पाइथन पक्ष के स्वामित्व में है, लेकिन फिर इसे बहुत जल्दी रिलीज़ किया जाएगा (जैसे ही मूल वापसी मूल्य अब संदर्भित नहीं किया जाता है) तो आपको मूल मूल्य को चारों ओर रखने की व्यवस्था करनी होगी लंबे समय तक। कि की एक पूरी उदाहरण है, जो रूप में लंबे समय सरणी आवरण के रूप में चारों ओर एक संदर्भ रखने के लिए सरणी वर्ग के उदाहरण के अंदर मूल सूचक बचाता ही होगा:
%module test
%pythonappend bar() %{
# Wrap it automatically
newval = fooArray.frompointer(val)
newval.ptr_retain = val
val = newval
%}
%newobject bar();
%inline %{
struct foo {
int member;
};
struct foo *bar() {
struct foo *arr = malloc(sizeof(struct foo) * 4);
for (int i = 0; i < 4; ++i)
arr[i].member = i;
return arr;
}
%}
%include <carrays.i>
%array_class(struct foo, fooArray);
सूचना यह है कि सरणी वर्ग इस उत्पन्न असीम है , सी में struct foo*
की तरह। इसका मतलब है कि आप पाइथन में इसे फिर से नहीं कर सकते - आकार अज्ञात है।यदि आकार वास्तव में तय किया गया है, या आपके पास आकार जानने का कोई तरीका है, तो आप इसे एक टाइपलिस्ट को लिखकर एक बहुत अच्छे (मेरे दृश्य में) तरीके से लपेट सकते हैं जो एक पाइलिस्ट देता है। यह लिखने के लिए थोड़ा और काम है, लेकिन इंटरफेस पाइथन पक्ष पर अच्छा लगता है।
क्या आपने यहां देखा है? - http://stackoverflow.com/questions/8114030/swig-python-array-inside- संरचना – dpandiar
@dpandiar - यह एक अलग मामला है क्योंकि आकार निश्चित और ज्ञात है और सरणी सदस्य हैं और फ़ंक्शन से मान वापस नहीं करते हैं – Flexo