返回向量< pair< int,int>>&从C ++方法到使用swig typemap的python元组列表 [英] Return vector<pair<int,int>> & from c++ method to python list of tuples using swig typemap

查看:51
本文介绍了返回向量< pair< int,int>>&从C ++方法到使用swig typemap的python元组列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having a lot of troubles trying to wrap a c++ method that returns a constant reference to a vector of pairs to a Python list of tuples using %typemap(out).

我目前有这样的东西:

myclass.h:

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:

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

myclass.i: (checking 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++;
    }
}

好吧,所以我不太了解的第一件事是typemap(out)的先前代码没有编译,因为它告诉我$ 1是指向容器的指针,而不是引用.当我更改将$ 1用作指针时,它可以编译但不能正常工作.

Ok so the first thing that I dont quite understand is that the previous code for the typemap (out) doesnt compile because it tells me that $1 is a pointer to the container not a reference. When I change the use of $1 as a pointer, it compiles but it doesnt work.

第二,在编译的情况下,typemap(in)可以工作(正确填充了c ++容器),但是当我尝试从python检索容器时,我得到了垃圾.当我将类似MyClass([((1,2)])之类的构造函数传递给构造函数时,我使用GetMyVector()返回一个Python列表,但它的大小为3,并且在元组上带有垃圾...我在做什么错???

Second, in the case that compiles, the typemap(in) works (the c++ container is correctly filled), but when I try to retrieve the container from python I get garbage. When I pass to the constructor something like MyClass([(1,2)]), and then I use GetMyVector() it returns a python list but of size 3 and with garbage on the tuples... what I'm doing wrong???

推荐答案

在这种情况下,不需要自定义类型映射.SWIG内置了对矢量和配对模板的支持,但是您必须声明配对模板以及矢量模板:

A custom typemap is not necessary for this case. SWIG has built-in support for vector and pair templates, but you have to declare the pair template as well as the vector template:

%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的整个生命周期中都保留对它的引用.例如:

But note because your class is written to hold a reference to the passed-in vector and not a copy, you have to hold a reference to it for the lifetime of MyClass. For example:

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

这篇关于返回向量&lt; pair&lt; int,int&gt;&gt;&amp;从C ++方法到使用swig typemap的python元组列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆