2012-02-27 11 views
6
di C++.

Ho implementato una classe con std::map in C++ e creato un'interfaccia utilizzando SWIG per essere chiamata da Java. Tuttavia non esiste un oggetto iteratore che mi consenta di scorrere le voci nel SWIG con lo spostamento std::map. Qualcuno sa come creare un iteratore?Nessun iteratore per Java quando si utilizza SWIG con std :: map

+0

Avrai bisogno di precisare cosa intendi per non "tutte" le voci. Qualcosa di specifico, come l'ultimo elemento mancante? Condivisione di un codice per mostrarci come hai fatto l'interop? –

+0

Siamo spiacenti, per la precisione non sono in grado di eseguire alcuna iterazione. – delita

+1

Una ricerca rapida di Google ha trovato questo: http://chadretz.wordpress.com/2009/11/27/stl-collections-with-java-and-swig/ Forse aiuta – Tim

risposta

10

Per poter eseguire l'iterazione su un oggetto in Java è necessario implementare Iterable. Ciò a sua volta richiede una funzione membro chiamata iterator() che restituisce un'implementazione adeguata di Iterator.

Dalla tua domanda non è chiaro se i tipi che stai usando nella mappa e se vuoi essere in grado di scorrere le coppie (come faresti in C++), le chiavi oi valori. Le soluzioni alle tre varianti sono sostanzialmente simili, il mio esempio qui sotto ha scelto i valori.

Per prima cosa, il preambolo per il file di interfaccia SWIG ho usato per testare questo:

%module test 

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

Al fine di attuare la mappa iterabile che ho dichiarato, definito e avvolto un'altra classe nel file di interfaccia SWIG . Questa classe, MapIterator implementa per noi l'interfaccia Iterator. È una combinazione di Java e C++ avvolto, in cui uno era più facile dell'altro da scrivere. In primo luogo alcuni Java, un typemap che dà l'interfaccia implementa e poi due dei tre metodi richiesti per l'interfaccia Iterable, fornita a 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(); 
    } 
%} 

Poi forniamo C++ parte MapIterator, che ha un privato implementazione di tutti tranne l'eccezione che lancia parte di next() e lo stato necessario per l'iteratore (espresso in termini di std::map proprio const_iterator).

%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;  
    }; 
%} 

Infine abbiamo bisogno di dire che la SWIG std::map stiamo avvolgendo implementa l'interfaccia Iterable e fornire una funzione di membro aggiuntivo ai fini del confezionamento std::map che restituisce una nuova istanza della classe MapIterator abbiamo appena scritto:

%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>; 

Questo potrebbe essere più generico, con le macro per esempio per nascondere i tipi di mappa in modo tale che se si dispone di più mappe è solo una questione di "chiamare" la macro per le mappe appropriate, proprio come si fa con %template .

C'è anche una piccola complicazione con le mappe di tipi primitivi - è necessario organizzare per il lato Java da utilizzare Double/Integer invece di double/int (autoboxing credo sia il termine), a meno che non hai deciso di avvolgere coppie già nel qual caso potresti fare una coppia con membri primitivi.

Problemi correlati