使用 swig 类型映射从 c++ 方法返回向量<pair<int,int>> & 到 python 元组列表

Posted

技术标签:

【中文标题】使用 swig 类型映射从 c++ 方法返回向量<pair<int,int>> & 到 python 元组列表【英文标题】:Return vector<pair<int,int>> & from c++ method to python list of tuples using swig typemap 【发布时间】:2013-11-21 15:43:13 【问题描述】:

我在尝试包装一个 c++ 方法时遇到了很多麻烦,该方法使用%typemap(out) 将一个对向量的常量引用返回到一个 Python 元组列表。

我目前有这样的事情:

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

好吧,我不太明白的第一件事是类型映射 (out) 的先前代码无法编译,因为它告诉我 $1 是指向容器的指针而不是引用。当我更改使用 $1 作为指针时,它会编译但它不起作用。

其次,在编译的情况下,typemap(in) 有效(c++ 容器已正确填充),但是当我尝试从 python 检索容器时,我得到了垃圾。当我将诸如 MyClass([(1,2)]) 之类的东西传递给构造函数时,然后我使用 GetMyVector() 它返回一个 python 列表,但大小为 3,并且元组上有垃圾......我做错了什么???

【问题讨论】:

【参考方案1】:

这种情况不需要自定义类型映射。 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 的生命周期内保存对它的引用。例如:

>>> del a
>>> b.GetMyVector()
*Undefined Behavior (crash, empty vector, etc.)*

【讨论】:

以上是关于使用 swig 类型映射从 c++ 方法返回向量<pair<int,int>> & 到 python 元组列表的主要内容,如果未能解决你的问题,请参考以下文章

类型映射资源并将列表转换为矢量(和返回)

如何使用 swig 将 c++ int** 返回值类型映射到 python

向量返回 const 引用,不可能向下转换

Swig:返回向量的接口简单 C++ 类

如何定义 swig 类型映射以将 unsigned char* 返回到 java

使用 SWIG 在 Python 中 C++ 类的奇怪行为