使用 SWIG 在 Python 中公开 std::list 成员

Posted

技术标签:

【中文标题】使用 SWIG 在 Python 中公开 std::list 成员【英文标题】:Expose std::list member in Python with SWIG 【发布时间】:2015-11-02 18:23:42 【问题描述】:

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

但是,我无法弄清楚要为 std::list 使用什么类型映射,它是我的 C++ 类的公共成员。

我的工作.h

class MyWork

public:

   // Functions

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

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

   // Properties

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

SWIG 类型映射

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


【问题讨论】:

【参考方案1】:

您可以只使用 SWIG 提供的类型映射。添加到您的 SWIG 接口文件:

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

完成!


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

为类生成访问器的包装代码来自 pointer 类型映射。

也就是说,你需要定义

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

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

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

【讨论】:

以上是关于使用 SWIG 在 Python 中公开 std::list 成员的主要内容,如果未能解决你的问题,请参考以下文章

通过 SWIG 在 python 中使用 std::ifstream、std::ofstream 的技术?

如何使用 Python 列表在 C++ 中使用 SWIG 分配 std::vector?

如何使用 swig C++ 命名空间作为 python 模块公开

包装 std::vector 的 std::vectors,C++ SWIG Python

Swig:在 Python 中使用 c++ STL 复杂

在 Python 中过早销毁的 SWIG 数组/类