2011-03-10 8 views
9

मुझे Wrap std::vector of std::vectors, C++ SWIG Python पर एक समान समस्या का सामना करना पड़ रहा है - लेकिन यह केवल सी ++ पार्सिंग नहीं है। मैं अपने सी ++ कोडवैड के लपेटा वेक्टर (सी ++ से पायथन) - इंजेक्टर वेक्टर को प्रॉक्सी ऑब्जेक्ट के रूप में कैसे पहचानें?

namespace ns { 
    typedef unsigned long long uint64_t; 
    typedef std::vector<uint64_t> Vector; 
    typedef std::vector<Vector> VectorOfVectors; 

    class MyClass { 
     /// ... 

     /// Returns a reference to the internal vector allocated in C++ land 
     const VectorOfVectors &GetVectors() const; 
    }; 
} 

में और बड़ा घूँट आवरण

%module myswig  
// ... 
%template(Uint64V) std::vector<ns::uint64_t>; 
%template(VUint64V) std::vector<std::vector<ns::uint64_t> >; 

तो रैपिंग ठीक काम करता है, वर्ग सहित निम्नलिखित है, और मैं वैक्टर की कक्षा के सदिश ठीक प्राप्त कर सकते हैं:

import myswig 
m = myswig.MyClass() 
v = m.GetVectors() 
print v 

कौन सा मुझे देता है:

<myswig.VUint64V; proxy of <Swig Object of type 'std::vector< std::vector< ns::uint64_t,std::allocator<ns::uint64_t> > > *' at 0x994a050> > 

लेकिन अगर मैं वेक्टर में किसी तत्व को एक्सेस करता हूं, तो मुझे प्रॉक्सी नहीं मिलती है जो एक myswig.Uint64V है - और यह मेरी समस्या है।

x = v[0] 
print x 

मैं पाने के लिए आशा करता हूँ क्या है:

<myswig.Uint64V; proxy of <Swig Object of type 'std::vector< ns::uint64_t, std::allocator<ns::uint64_t> > *' at 0x994a080> > 

इसके बजाय, मैं हो रही है:

(<Swig Object of type 'ns::uint64_t *' at 0x994a080>, <Swig Object of type 'ns::uint64_t *' at 0x994a098>) 

है, वैक्टर की वेक्टर में सूचकांक मुझे दे रहा है एक 2-एंट्री टुपल, और मुझे वेक्टर क्लास की प्रॉक्सी नहीं है जो मुझे चाहिए (ताकि आंतरिक वेक्टर तक पहुंच अन्य वैक्टरों तक पहुंचने जितनी आसान हो)।

मैं भी चेतावनी हो रही है: वहाँ एक नाशक इस प्रकार के लिए परिभाषित नहीं है

swig/python detected a memory leak of type 'ns::uint64_t *', no destructor found. 

क्योंकि निश्चित रूप से।

कोई विचार?

उत्तर

10

मैंने इस पर एक सहयोगी के साथ काम किया, और हम कुछ समाधानों के साथ आने में कामयाब रहे हैं।

सबसे पहले, बड़ा घूँट मैं फ़ाइल में, यह महत्वपूर्ण इस पूर्वप्रक्रमक चर को परिभाषित करने के लिए:,

%{ 
# define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
%} 

और फिर) यह सुनिश्चित करने के संदर्भ में इस तरह के सामने (जैसे तरीकों से लौटे वापस() , ऑपरेटर [], आदि वास्तव में आंतरिक वेक्टर के लिए सही प्रॉक्सी प्रकार का उल्लेख किया जाता है, तो निम्न typemaps मदद:

// In pop() 
%typemap(out) std::vector<std::vector<ns::uint64_t> >::value_type { 
$result = SWIG_NewPointerObj(SWIG_as_voidptr(&$1), $descriptor(std::vector<ns::uint64_t>), 0 | 0); 
} 

// In front(), back(), __getitem__() 
%typemap(out) std::vector<std::vector<ns::uint64_t> >::value_type & { 
    $result = SWIG_NewPointerObj(SWIG_as_voidptr($1), $descriptor(std::vector<ns::uint64_t>), 0 | 0); 
} 

हम यह भी पता चला है कि अगर आप एनएस :: uint64_t चाहते एक अजगर लंबे समय के रूप में देखा जाना चाहिए परिवर्तनीय (एक सी के बराबर लंबे समय तक हस्ताक्षर किए गए) तो कुछ और टाइपमैप एस को मूल्यों और संदर्भों का उपयोग करके वेक्टर विधियों को सुनिश्चित करने के लिए आवश्यक था, इसके बजाय 64-बिट पूर्णांक मानों का उपयोग करें।

// In __getitem__() 
%typemap(out) ns::uint64_t { 
    $result = PyLong_FromUnsignedLongLong($1); 
} 
// Not used (but probably useful to have, just in case) 
%typemap(in) ns::uint64_t { 
    $1 = PyLong_AsUnsignedLongLong($input); 
} 
// In pop() 
%typemap(out) std::vector<ns::uint64_t>::value_type { 
    $result = PyLong_FromUnsignedLongLong($1); 
} 
// In __getitem__(), front(), back() 
%typemap(out) std::vector<ns::uint64_t>::value_type & { 
    $result = PyLong_FromUnsignedLongLong(*$1); 
} 
// In __setitem__(), append(), new Uint64Vector, push_back(), assign(), resize(), insert() 
// This allows a python long literal number to be used as a parameter to the above methods. 
// Note the use of a local variable declared at the SWIG wrapper function scope, 
// by placing the variable declaration in parentheses() prior to the open brace { 
%typemap(in) std::vector<ns::uint64_t>::value_type & (std::vector<ns::uint64_t>::value_type temp) { 
    temp = PyLong_AsUnsignedLongLong($input); 
    $1 = &temp; 
} 

मुझे आशा है कि यह समाधान भविष्य में लोगों की सहायता करेगा!

+0

मुझे कॉन्स्ट रेफरेंस और पॉइंटर और कॉन्स पॉइंटर बाध्यकारी के साथ समस्या है, क्या आप अधिक जानकारी प्रदान कर सकते हैं? – squid

+0

परिभाषित लाइन बहुत महत्वपूर्ण है ...... लेकिन यह एक ही समय में अस्पष्ट है ..... मुझे आश्चर्य है कि आप इसे कैसे पाते हैं। – squid

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