2012-02-27 13 views
6

मैं सी में std::map के साथ एक वर्ग को लागू किया है ++ और बड़ा घूँट का उपयोग कर जावा से फोन होने के लिए इंटरफ़ेस बनाया। हालांकि कोई इटरेटर ऑब्जेक्ट नहीं है जो मुझे SWIG wrapped std::map में प्रविष्टियों के माध्यम से पुन: सक्रिय करने की अनुमति देता है। क्या कोई जानता है कि एक इटरेटर कैसे बनाया जाए?जावा के लिए कोई इटरेटर जब सी ++ के एसटीडी के साथ बड़ा घूँट का उपयोग कर :: नक्शा

+0

आपको "सभी" प्रविष्टियों से आपका मतलब सटीक करने की आवश्यकता होगी। कुछ भी विशिष्ट, आखिरी वस्तु की तरह गायब है? हमें यह दिखाने के लिए कुछ कोड साझा करना कि आपने इंटरऑप कैसे किया? –

+0

क्षमा करें, सटीक होने के लिए मैं किसी भी पुनरावृत्ति को करने में असमर्थ हूं। – delita

+1

एक त्वरित Google खोज ने यह पाया: http://chadretz.wordpress.com/2009/11/27/stl-collections-with-java-and-swig/ शायद यह मदद करता है – Tim

उत्तर

10

आदेश में जावा में एक वस्तु यह Iterable को लागू करने की जरूरत है से अधिक पुनरावृति करने में सक्षम हो। इसके बदले में एक सदस्य फ़ंक्शन की आवश्यकता होती है जिसे iterator() कहा जाता है जो Iterator का उपयुक्त कार्यान्वयन देता है।

अपने प्रश्न से यह स्पष्ट नहीं है कि आप मानचित्र में किस प्रकार का उपयोग कर रहे हैं और यदि आप जोड़ों (जैसे आप सी ++ में), चाबियाँ या मानों में पुन: सक्रिय करने में सक्षम होना चाहते हैं। तीन प्रकारों के समाधान काफी समान हैं, नीचे दिए गए मेरे उदाहरण ने मूल्यों को चुना है।

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

%module test 

%include "std_string.i" 
%include "std_map.i" 

आदेश iterable नक्शा मैं, घोषित किया है परिभाषित और बड़ा घूँट इंटरफ़ेस फ़ाइल में अन्य वर्ग लिपटे लागू करने के लिए । यह वर्ग, MapIterator हमारे लिए Iterator इंटरफ़ेस लागू करता है। यह जावा और लपेटा सी ++ दोनों का मिश्रण है, जहां दूसरे लिखने के लिए एक आसान था। सबसे पहले कुछ जावा, एक typemap कि इंटरफ़ेस को लागू करता है और उसके बाद Iterable इंटरफेस के लिए आवश्यक तीन विधियों में से दो देता है, एक typemap के रूप में दिया:

%typemap(javainterfaces) MapIterator "java.util.Iterator<String>" 
%typemap(javacode) MapIterator %{ 
    public void remove() throws UnsupportedOperationException { 
    throw new UnsupportedOperationException(); 
    } 

    public String next() throws java.util.NoSuchElementException { 
    if (!hasNext()) { 
     throw new java.util.NoSuchElementException(); 
    } 

    return nextImpl(); 
    } 
%} 

फिर हम सी ++ MapIterator का हिस्सा है, जो एक निजी है आपूर्ति (std::map की खुद const_iterator के संदर्भ में व्यक्त) सभी लेकिन अपवाद next() का हिस्सा है और राज्य इटरेटर के लिए आवश्यक फेंकने के कार्यान्वयन।

%javamethodmodifiers MapIterator::nextImpl "private"; 
%inline %{ 
    struct MapIterator { 
    typedef std::map<int,std::string> map_t; 
    MapIterator(const map_t& m) : it(m.begin()), map(m) {} 
    bool hasNext() const { 
     return it != map.end(); 
    } 

    const std::string& nextImpl() { 
     const std::pair<int,std::string>& ret = *it++; 
     return ret.second; 
    } 
    private: 
    map_t::const_iterator it; 
    const map_t& map;  
    }; 
%} 

अंत में हम बड़ा घूँट बताया कि std::map हम औजार लपेटकर रहे Iterable इंटरफेस और std::map जो MapIterator वर्ग हम सिर्फ लिखा का एक नया उदाहरण देता लपेटकर के प्रयोजनों के लिए एक अतिरिक्त सदस्य समारोह प्रदान करने की आवश्यकता:

%typemap(javainterfaces) std::map<int,std::string> "Iterable<String>" 

%newobject std::map<int,std::string>::iterator() const; 
%extend std::map<int,std::string> { 
    MapIterator *iterator() const { 
    return new MapIterator(*$self); 
    } 
} 

%template(MyMap) std::map<int,std::string>; 

यह उदाहरण नक्शा ऐसी है कि वह सिर्फ "बुला" का सवाल है कि अगर आप एक से अधिक नक्शे के प्रकार को छिपाने के लिए के लिए अधिक सामान्य, मैक्रोज़ के साथ हो सकता है उचित नक्शे के लिए मैक्रो, जैसा कि आपने %template के साथ क्या ।

वहाँ भी आदिम प्रकार के नक्शे के साथ एक मामूली जटिलता है - आप की व्यवस्था करने के जावा पक्ष Double/Integer के बजाय का उपयोग करने के लिए की आवश्यकता होगी double/int (autoboxing मेरा मानना ​​है कि शब्द है), जब तक आप जोड़े लपेटो करने का निर्णय लिया पहले से ही आप किस मामले में आदिम सदस्यों के साथ एक जोड़ी बना सकते हैं।

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