2013-11-21 52 views
5

我遇到了很多麻煩,試圖包裝一個C++方法,該方法返回對Python對象向量的常量引用元組使用%typemap(out)返回矢量<pair <int,int>>&從C++方法到python使用swig類型映射的元組列表

我現在有這樣的事情:

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:(檢查中省略)

%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 hing,我不太明白的是前面的typemap(out)代碼不會編譯,因爲它告訴我$ 1是指向容器而不是引用的指針。當我將$ 1作爲指針使用時,它會編譯,但它不起作用。

其次,在編譯的情況下,typemap(in)工作(C++容器被正確填充),但是當我嘗試從python檢索容器時,我得到垃圾。當我傳遞給構造函數像MyClass([(1,2)]),然後我使用GetMyVector()它返回一個python列表,但大小爲3,並在元組上有垃圾...我做錯了什麼???

回答

7

對於這種情況,自定義的typemap不是必需的。痛飲有內置的矢量和對模板的支持,但你必須聲明對模板以及矢量模板:

%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的整個生命週期中持有引用。例如:

​​
相關問題