使用 SWIG 公开 Python 中的 std::list 成员
Expose std::list member in Python with SWIG
在 C++ 函数的输出或输入中使用 std::list 时,我已经能够使用以下类型映射。这些类型映射允许我将列表对象用作 Python.
中的标准列表
但是,我无法弄清楚 std::list 使用什么类型映射,它是我的 C++ class.
的 public 成员
MyWork.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=.begin() ; it != .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
// 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);
}
= listTemp;
}
else
{
PyErr_SetString(PyExc_TypeError,"Wrong argument type, list expected");
return NULL;
}
}
您可以只使用 SWIG 提供的类型映射。添加到您的 SWIG 接口文件:
%include "std_list.i"
%include "MyClass.h" //(or declaration of MyClass)
%template(MyClassList) std::list<MyClass>;
%include "MyWork.h"
完成!
您的实际问题(访问结构成员变量需要哪些类型映射)的答案可以在 here SWIG 文档中找到:
The wrapper code to generate the accessors for classes comes from the pointer typemaps.
即,您需要定义
%typemap(in) std::list<MyClass> *
%typemap(out) std::list<MyClass> *
然而,正如同一节所述,使用 %naturalvar
指令可能是有意义的,然后访问器将使用 const &
类型映射,即你需要定义
%typemap(in) const std::list<MyClass> &
%typemap(out) const std::list<MyClass> &
在 C++ 函数的输出或输入中使用 std::list 时,我已经能够使用以下类型映射。这些类型映射允许我将列表对象用作 Python.
中的标准列表但是,我无法弄清楚 std::list 使用什么类型映射,它是我的 C++ class.
的 public 成员MyWork.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=.begin() ; it != .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
// 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);
}
= listTemp;
}
else
{
PyErr_SetString(PyExc_TypeError,"Wrong argument type, list expected");
return NULL;
}
}
您可以只使用 SWIG 提供的类型映射。添加到您的 SWIG 接口文件:
%include "std_list.i"
%include "MyClass.h" //(or declaration of MyClass)
%template(MyClassList) std::list<MyClass>;
%include "MyWork.h"
完成!
您的实际问题(访问结构成员变量需要哪些类型映射)的答案可以在 here SWIG 文档中找到:
The wrapper code to generate the accessors for classes comes from the pointer typemaps.
即,您需要定义
%typemap(in) std::list<MyClass> *
%typemap(out) std::list<MyClass> *
然而,正如同一节所述,使用 %naturalvar
指令可能是有意义的,然后访问器将使用 const &
类型映射,即你需要定义
%typemap(in) const std::list<MyClass> &
%typemap(out) const std::list<MyClass> &