2

I've been able to use the following typemaps when using a std::list in output or input of a function in C++. These typemaps allow me to use the list object as a standard list in Python.

However, I haven't been able to figure out what typemap to use for a std::list which is a public member of my C++ class.

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 Typemaps

%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 Answer 1

1

You can just use the typemaps provided by SWIG. Add to your SWIG interface file:

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

Done!


The answer to your actual question (what typemaps are required to access structure member variables) can be found here in the SWIG documentation:

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

I.e., you need to define

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

However, as stated in that same section, it probably makes sense to use the %naturalvar directive, and then accessors will use the const & typemaps, i.e., you then need to define

%typemap(in) const std::list<MyClass> &
%typemap(out) const std::list<MyClass> &
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.