关于c ++:使用SWIG在Python中公开std :: list成员

Expose std::list member in Python with SWIG

在使用C++中的函数的输出或输入时,我已经能够使用下面的类型映射。这些类型映射允许我在Python中将List对象用作标准列表。

但是,我还没有弄清楚对于Std::ListType使用的类型映射是什么,它是我C++类的一个公共成员。

我的作品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyWork
{
public:

   // Functions

   void myFunc1(std::list<MyClass> my_list); // OK

   std::list<MyClass> myFunc2(); // OK

   // Properties

   std::list<MyClass> MyList; // ????
};

SWIG类型映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
%typemap(out) std::list<MyClass>
{
PyObject* outList = PyList_New(0);

int error;

std::list<MyClass>::iterator it;
for ( it=$1.begin() ; it != $1.end(); it++ )
{
    PyObject* pyMyClass = SWIG_NewPointerObj(new MyClass(*it), SWIGTYPE_p_MyClass, SWIG_POINTER_OWN );

    error = PyList_Append(outList, pyMyClass);
    Py_DECREF(pyMyClass);
    if (error) SWIG_fail;      
}

$result = outList;
}

%typemap(in) std::list<MyClass>
{
//$input is the PyObject
//$1 is the parameter

if (PyList_Check($input))
{
    std::list<MyClass> listTemp;

    for(int i = 0; i<PyList_Size($input); i++)
    {
        PyObject* pyListItem = PyList_GetItem($input, i);

        MyClass* arg2 = (MyClass*) 0 ;

        int res1 = 0;
        void *argp1;

        res1 = SWIG_ConvertPtr(pyListItem, &argp1, SWIGTYPE_p_MyClass,  0  | 0);
        if (!SWIG_IsOK(res1))
        {
            PyErr_SetString(PyExc_TypeError,"List must only contain MyClassobjects");
            return NULL;
        }  
        if (!argp1)
        {
            PyErr_SetString(PyExc_TypeError,"Invalid null reference for object MyClass");
            return NULL;
        }

        arg2 = reinterpret_cast< MyClass* >(argp1);
        listTemp.push_back(*arg2);
    }

    $1 = listTemp;
}
else
{
    PyErr_SetString(PyExc_TypeError,"Wrong argument type, list expected");
    return NULL;
}
}

您只需使用Swig提供的打印地图即可。添加到swig接口文件:

1
2
3
4
%include"std_list.i"
%include"MyClass.h" //(or declaration of MyClass)
%template(MyClassList) std::list<MyClass>;
%include"MyWork.h"

完成!

您的实际问题的答案(需要什么样的类型映射来访问结构成员变量)可以在SWIG文档中找到:

The wrapper code to generate the accessors for classes comes from the pointer typemaps.

也就是说,你需要定义

1
2
%typemap(in) std::list<MyClass> *
%typemap(out) std::list<MyClass> *

但是,正如在同一节中所述,使用%naturalvar指令可能是有意义的,然后访问器将使用const &类型映射,即您需要定义

1
2
%typemap(in) const std::list<MyClass> &
%typemap(out) const std::list<MyClass> &