2012-02-27 6 views
6

C++でstd::mapのクラスを実装し、SWIGを使用してJavaからコールするインターフェイスを作成しました。しかし、イテレータオブジェクトがないので、SWIGのエントリを繰り返し処理することができます。std::map。誰もイテレータを作成する方法を知っていますか?C++のstd :: mapでSWIGを使用する場合、Javaのイテレータはありません

+0

「すべて」の項目ではないことを正確に示す必要があります。最後のアイテムが見つからない場合は、具体的なものは何ですか?相互運用性の仕組みを示すコードを共有していますか? –

+0

申し訳ありませんが、正確に言えば、私は反復を全く実行することができません。 – delita

+1

すばらしいGoogle検索でこれが見つかりました:http://chadretz.wordpress.com/2009/11/27/stl-collections-with-java-and-swig/多分役立つでしょう – Tim

答えて

10

Javaでオブジェクトを反復処理できるようにするには、Iterableを実装する必要があります。これには、Iteratorの適切な実装を返すiterator()というメンバ関数が必要です。

マップからどのタイプを使用しているのか、ペア(C++の場合のように)、キーまたは値を繰り返し処理できるようにしたいのかどうかは疑問です。 3つの変形に対する解決法は実質的に同様であり、以下の例では値を選択した。最初

まず、物事、私はこれをテストするために使用SWIGインタフェースファイルのためのプリアンブル:反復可能なマップを実現するために

%module test 

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

私は、宣言に定義され、SWIGインタフェースファイル内の別のクラスをラップしました。このクラスのMapIteratorは、Iteratorインターフェイスを実装しています。これは、JavaとラップされたC++が混在していて、他のものよりも簡単に書くことができます。まずタイプマップとして与えられたいくつかのJava、それは実装インタフェースとIterableインターフェイスに必要な3つの方法の2つを与えるタイプマップ、:

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

はその後、我々はプライベートを持っているC++ MapIteratorの一部を供給next()の例外をスローする例外を除くすべての実装と、イテレータに必要な状態(std::map自身の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;  
    }; 
%} 

は最後にstd::map我々がIterableインタフェース実装をラップしていることをSWIGを伝え、私達はちょうど書いたMapIteratorクラスの新しいインスタンスを返しますstd::mapをラップする目的のために、余分なメンバ関数を提供する必要があります。

%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/intDouble/Integerを使用するJava側の手配をする必要がありますすでにプリミティブメンバーとペアを組むことができます。

関連する問題