% typemapping de una biblioteca de C ++ para la interfaz de Python

Quiero crear un contenedor python para mi biblioteca C ++. Sería genial si hubiera una conversión automática de std :: vector a las listas de python y al revés. Desafortunadamente, si agrego este código a mi archivo de interfaz, todavía recibo errores en tiempo de ejecución.

%typemap(in) std::vector value (std::vector vIn) { int iLen = PySequence_Length($input); for(unsigned int i = 0; i < iLen; i++) { PyObject *o = PySequence_GetItem($input, i); if (PyNumber_Check(o)) { vIn.push_back((float)PyFloat_AsDouble(o) ); } } $1 = vIn; } %typemap(out) std::vector { std::vector vOut = $1; int iLen = vOut.size(); $result = PyList_New(iLen); for(unsigned int i = 0; i < iLen; i++) { double fVal = vOut.at(i); PyObject *o = PyFloat_FromDouble((double) fVal); PyList_SetItem($result, i, o); } } 

Encabezado de la clase:

 class TrainingSet { private: std::vector<std::vector > m_vInputList; std::vector<std::vector > m_vOutputList; public: void AddInput(const std::vector &vIn); // .. 

Código Python:

 trainSet = TrainingSet() trainSet.AddInput([0.5, 0.5, 0.5]) 

Error:

 File "runSOMNet.py", line 9, in  trainSet.AddInput([0.5, 0.5, 0.5]) File "/home/dgrat/annetgpgpu/build/ANNet/ANPyNetCPU.py", line 674, in AddInput def AddInput(self, *args): return _ANPyNetCPU.TrainingSet_AddInput(self, *args) NotImplementedError: Wrong number or type of arguments for overloaded function 'TrainingSet_AddInput'. Possible C/C++ prototypes are: ANN::TrainingSet::AddInput(std::vector< float,std::allocator > const &) ANN::TrainingSet::AddInput(float *,unsigned int const &) 

Si va a definir el %typemap s manualmente, también necesitará un %typemap(check) , algo como:

 %typemap(typecheck) std::vector& { $1 = PySequence_Check($input) ? 1 : 0; } 

Creo que la regla de oro es que si define un %typemap(in) , también debe definir un %typemap(check) — de lo contrario, el código generado nunca llega a donde se coloca su %typemap(in) .

La biblioteca std_vector.i en SWIG proporciona soporte para std::vector .

http://www.swig.org/Doc2.0/Library.html#Library_stl_cpp_library

Solo debe informar a SWIG sobre las instancias de la plantilla que desea que conozca:

 %include "std_vector.i" namespace std { %template(FloatVector) vector; } 

Tenga en cuenta que el siguiente código de Python funcionará, pero incurrirá en una copia de matriz:

 for x in range(0, 3): list[x] = x myModule.myFunction(list) 

Para hacer lo mismo sin incurrir en una copia, construya la lista utilizando el constructor de objetos proxy generado por SWIG:

 list = myModule.FloatVector() for x in range(0, 3): list[x] = x myModule.myFunction(list)