2013-11-21 11 views
5

ペアのベクトルへの定数参照をPythonリストに返すC++メソッドをラップしようとすると、タプルは%typemap(out)です。swigのtypemapを使用してC++メソッドからタプルのリストにベクトル<pair <int,int>>を返します。

myclass.h:

#inlcude <vector> 
using std::vector; 
class MyClass { 
private: 
    const vector<pair<int,int>> & _myvector; 
public: 
    MyClass(const vector<pair<int,int>> & myvector); 
    const vector<pair<int,int>> & GetMyVector() const; 
} 

myclass.cpp:

#include "myclass.h" 

MyClass::MyClass(const vector<pair<int,int>> & myvector): _myvector(myvector){}; 

const vector<pair<int,int>> & MyClass::GetMyVector() const { 
    return _myvector; 
}; 

myclass.i:(ommitedチェック)

%module MyClass 
%include "std_vector.i" 

namespace std { 
    %template(vector_pair_int) vector<pair<int,int>>; 
} 

%typemap(in) (const vector_pair_int &){ 

    $1 = new vector<pair<int,int>>; 
    int size = PyList_Size($input); 
    for (int i=0; i<size; i++){ 
     PyObject *o = PyList_GetItem($input,i); 
     PyObject *o1 = PyList_GetItem(o,0); 
     PyObject *o2 = PyList_GetItem(o,1); 
     $1->push_back(make_pair(PyInt_AsLong(o1),PyInt_AsLong(o2))) 
} 

} 

%typemap(out) (const vector_pair_int &) { 
    $result = PyList_New($1.size()); 
    vector<pair<int,int>>:: const_iterator it; 
    int count=0; 
    for (it= $1.begin(); it!= $1.end(); ++it){ 
     PyObject * tup = PyTuple_Pack(2, it->first,it->second); 
     PyList_SET_ITEM($result,count,tup); 
     count++; 
    } 
} 

は、私は現在、このようなものを持っています

さて、最初のt私が理解していないヒンジは、$ 1がコンテナへのポインタであることを私に伝えるため、typemap(out)の前のコードはコンパイルされません。ポインタとしての$ 1の使用を変更するとコンパイルされますが、それは動作しません。

第2に、コンパイルする場合、typemap(in)が機能します(C++コンテナは正しく埋められます)。しかし、Pythonからコンテナを取得しようとすると、ゴミが出ます。コンストラクタにMyClass([(1,2)]のようなものを渡した後、GetMyVector()を使用してpythonリストを返しますが、サイズが3で、タプルにガベージがあります...私が間違っている???

答えて

7

この場合、カスタムタイプマップは必要ありません。 SWIGはベクトルとペアテンプレートのサポートを内蔵していますが、あなたはペアのテンプレートだけでなく、ベクトルテンプレートを宣言する必要があります。

%module x 

%include <std_pair.i> 
%include <std_vector.i> 
%include <std_string.i> 
%template() std::pair<int,int>; 
%template(PairVector) std::vector<std::pair<int,int> >; 

%{ 
#include "MyClass.h" 
%} 

%include "MyClass.h" 

例:

>>> import x 
>>> a=x.PairVector(((1,2),(3,4),(5,6))) 
>>> b=x.MyClass(a) 
>>> b.GetMyVector() 
((1, 2), (3, 4), (5, 6)) 

しかしノートあなたのクラスが書かれているので、コピーされていない渡されたベクターへの参照を保持するには、MyClassの存続期間中に参照を保持する必要があります。例:

​​
関連する問題