I'm trying to figure out how to use SWIG to wrap a c++ function that returns 2d vector to python.I have the file functions.h
#include <vector>
std::vector< std::vector<double> > array_mean(std::vector< std::vector<double> > array)
{
std::vector< std::vector<double> > mean_array( rows, std::vector<double>(cols));
....
return mean_array;
}
In the interface file functions.i I have
%module functions
%{
#include "functions.h"
%}
%include "std_vector.i"
namespace std {
%template(VecVecdouble) vector< vector<double> >;
}
%include "functions.h"
Then I perform
swig -c++ -python functions.i
g++ -O2 -fPIC -c functions_wrap.cxx -I/usr/include/python2.4 -I/usr/lib/python2.4
And the compiler spits out a bunch of errors.
functions_wrap.cxx: In function 'bool swig::check(PyObject*) [with Type = double]':
functions_wrap.cxx:3763: instantiated from 'bool swig::PySequence_Cont<T>::check(bool) const [with T = double]'
functions_wrap.cxx:3820: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<double, std::allocator<double> >, T = double]'
Any idea what is the problem? Thanks.
edit to include the complete compiler output
functions_wrap.cxx:3878: instantiated from 'static int
swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = double]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3152: instantiated from 'static bool swig::traits_check<Type, swig::pointer_category>::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3159: instantiated from 'bool swig::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3763: instantiated from 'bool swig::PySequence_Cont<T>::check(bool) const [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3820: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3878: instantiated from 'static int swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >]'
functions_wrap.cxx:4946: instantiated from here
functions_wrap.cxx:3159: error: no type named 'category' in 'struct swig::traits<double>'
functions_wrap.cxx: In function 'const char* swig::type_name() [with Type = double]':
functions_wrap.cxx:2946: instantiated from 'static swig_type_info* swig::traits_info<Type>::type_info() [with Type = double]'
functions_wrap.cxx:2953: instantiated from 'swig_type_info* swig::type_info() [with Type = double]'
functions_wrap.cxx:2987: instantiated from 'static PyObject* swig::traits_from_ptr<Type>::from(Type*, int) [with Type = double]'
functions_wrap.cxx:2993: instantiated from 'static PyObject* swig::traits_from<Type>::from(const Type&) [with Type = double]'
functions_wrap.cxx:3005: instantiated from 'PyObject* swig::from(const Type&) [with Type = double]'
functions_wrap.cxx:3862: instantiated from 'static PyObject* swig::traits_from_stdseq<Seq, T>::from(const Seq&) [with Seq = std::vector<double, std::allocator<double> >, T = double]'
functions_wrap.cxx:3885: instantiated from 'static PyObject* swig::traits_from<std::vector<T, std::allocator<_CharT> > >::from(const std::vector<T, std::allocator<_CharT> >&) [with T = double]'
functions_wrap.cxx:3005: instantiated from 'PyObject* swig::from(const Type&) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3862: instantiated from 'static PyObject* swig::traits_from_stdseq<Seq, T>::from(const Seq&) [with Seq = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3885: instantiated from 'static PyObject* swig::traits_from<std::vector<T, std::allocator<_CharT> > >::from(const std::vector<T, std::allocator<_CharT> >&) [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3005: instantiated from 'PyObject* swig::from(const Type&) [with Type = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >]'
functions_wrap.cxx:6430: instantiated from here
functions_wrap.cxx:2936: error: 'type_name' is not a member of 'swig::traits<double>'
functions_wrap.cxx: In function 'Type swig::as(PyObject*, bool) [with Type = double]':
functions_wrap.cxx:3563: instantiated from 'swig::PySequence_Ref<T>::operator T() const [with T = double]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:285: instantiated from 'static _OI std::__copy<_BoolType, std::random_access_iterator_tag>::copy(_II, _II, _OI) [with _II = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OI = double*, bool _BoolType = false]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:317: instantiated from '_OI std::__copy_aux(_II, _II, _OI) [with _II = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OI = double*]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:326: instantiated from 'static _OI std::__copy_normal<<anonymous>, <anonymous> >::copy_n(_II, _II, _OI) [with _II = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OI = double*, bool <anonymous> = false, bool <anonymous> = false]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:387: instantiated from '_OutputIterator std::copy(_InputIterator, _InputIterator, _OutputIterator) [with _InputIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OutputIterator = double*]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/vector.tcc:230: instantiated from 'void std::vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _Tp = double, _Alloc = std::allocator<double>]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_vector.h:853: instantiated from 'void std::vector<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator, _InputIterator, __false_type) [with _InputIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _Tp = double, _Alloc = std::allocator<double>]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_vector.h:319: instantiated from 'void std::vector<_Tp, _Alloc>::assign(_InputIterator, _InputIterator) [with _InputIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _Tp = double, _Alloc = std::allocator<double>]'
functions_wrap.cxx:3801: instantiated from 'void swig::assign(const PySeq&, Seq*) [with PySeq = swig::PySequence_Cont<double>, Seq = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3816: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<double, std::allocator<double> >, T = double]'
functions_wrap.cxx:3878: instantiated from 'static int swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = double]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3152: instantiated from 'static bool swig::traits_check<Type, swig::pointer_category>::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3159: instantiated from 'bool swig::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3763: instantiated from 'bool swig::PySequence_Cont<T>::check(bool) const [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3820: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3878: instantiated from 'static int swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >]'
functions_wrap.cxx:4946: instantiated from here
functions_wrap.cxx:3138: error: no type named 'category' in 'struct swig::traits<double>'
[jdensmor@ls10977 test]$ g++ -O2 -fPIC -c functions_wrap.cxx -I/usr/include/python2.4 -I/usr/lib/python2.4
functions_wrap.cxx: In function 'bool swig::check(PyObject*) [with Type = double]':
functions_wrap.cxx:3763: instantiated from 'bool swig::PySequence_Cont<T>::check(bool) const [with T = double]'
functions_wrap.cxx:3820: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<double, std::allocator<double> >, T = double]'
functions_wrap.cxx:3878: instantiated from 'static int swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = double]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3152: instantiated from 'static bool swig::traits_check<Type, swig::pointer_category>::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3159: instantiated from 'bool swig::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3763: instantiated from 'bool swig::PySequence_Cont<T>::check(bool) const [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3820: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3878: instantiated from 'static int swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >]'
functions_wrap.cxx:4946: instantiated from here
functions_wrap.cxx:3159: error: no type named 'category' in 'struct swig::traits<double>'
functions_wrap.cxx: In function 'const char* swig::type_name() [with Type = double]':
functions_wrap.cxx:2946: instantiated from 'static swig_type_info* swig::traits_info<Type>::type_info() [with Type = double]'
functions_wrap.cxx:2953: instantiated from 'swig_type_info* swig::type_info() [with Type = double]'
functions_wrap.cxx:2987: instantiated from 'static PyObject* swig::traits_from_ptr<Type>::from(Type*, int) [with Type = double]'
functions_wrap.cxx:2993: instantiated from 'static PyObject* swig::traits_from<Type>::from(const Type&) [with Type = double]'
functions_wrap.cxx:3005: instantiated from 'PyObject* swig::from(const Type&) [with Type = double]'
functions_wrap.cxx:3862: instantiated from 'static PyObject* swig::traits_from_stdseq<Seq, T>::from(const Seq&) [with Seq = std::vector<double, std::allocator<double> >, T = double]'
functions_wrap.cxx:3885: instantiated from 'static PyObject* swig::traits_from<std::vector<T, std::allocator<_CharT> > >::from(const std::vector<T, std::allocator<_CharT> >&) [with T = double]'
functions_wrap.cxx:3005: instantiated from 'PyObject* swig::from(const Type&) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3862: instantiated from 'static PyObject* swig::traits_from_stdseq<Seq, T>::from(const Seq&) [with Seq = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3885: instantiated from 'static PyObject* swig::traits_from<std::vector<T, std::allocator<_CharT> > >::from(const std::vector<T, std::allocator<_CharT> >&) [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3005: instantiated from 'PyObject* swig::from(const Type&) [with Type = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >]'
functions_wrap.cxx:6430: instantiated from here
functions_wrap.cxx:2936: error: 'type_name' is not a member of 'swig::traits<double>'
functions_wrap.cxx: In function 'Type swig::as(PyObject*, bool) [with Type = double]':
functions_wrap.cxx:3563: instantiated from 'swig::PySequence_Ref<T>::operator T() const [with T = double]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:285: instantiated from 'static _OI std::__copy<_BoolType, std::random_access_iterator_tag>::copy(_II, _II, _OI) [with _II = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OI = double*, bool _BoolType = false]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:317: instantiated from '_OI std::__copy_aux(_II, _II, _OI) [with _II = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OI = double*]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:326: instantiated from 'static _OI std::__copy_normal<<anonymous>, <anonymous> >::copy_n(_II, _II, _OI) [with _II = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OI = double*, bool <anonymous> = false, bool <anonymous> = false]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:387: instantiated from '_OutputIterator std::copy(_InputIterator, _InputIterator, _OutputIterator) [with _InputIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _OutputIterator = double*]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/vector.tcc:230: instantiated from 'void std::vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _Tp = double, _Alloc = std::allocator<double>]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_vector.h:853: instantiated from 'void std::vector<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator, _InputIterator, __false_type) [with _InputIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _Tp = double, _Alloc = std::allocator<double>]'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_vector.h:319: instantiated from 'void std::vector<_Tp, _Alloc>::assign(_InputIterator, _InputIterator) [with _InputIterator = swig::PySequence_InputIterator<double, const swig::PySequence_Ref<double> >, _Tp = double, _Alloc = std::allocator<double>]'
functions_wrap.cxx:3801: instantiated from 'void swig::assign(const PySeq&, Seq*) [with PySeq = swig::PySequence_Cont<double>, Seq = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3816: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<double, std::allocator<double> >, T = double]'
functions_wrap.cxx:3878: instantiated from 'static int swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = double]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3152: instantiated from 'static bool swig::traits_check<Type, swig::pointer_category>::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3159: instantiated from 'bool swig::check(PyObject*) [with Type = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3763: instantiated from 'bool swig::PySequence_Cont<T>::check(bool) const [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3820: instantiated from 'static int swig::traits_asptr_stdseq<Seq, T>::asptr(PyObject*, Seq**) [with Seq = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3878: instantiated from 'static int swig::traits_asptr<std::vector<T, std::allocator<_CharT> > >::asptr(PyObject*, std::vector<T, std::allocator<_CharT> >**) [with T = std::vector<double, std::allocator<double> >]'
functions_wrap.cxx:3030: instantiated from 'int swig::asptr(PyObject*, Type**) [with Type = std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >]'
functions_wrap.cxx:4946: instantiated from here
functions_wrap.cxx:3138: error: no type named 'category' in 'struct swig::traits<double>'
Your failed to export the inner vector type as well.
%module functions
%{
#include "functions.h"
%}
%include "std_vector.i"
namespace std {
%template(VecDouble) vector<double>;
%template(VecVecdouble) vector< vector<double> >;
}
%include "functions.h"
On a side note, generating the -csharp output from SWIG is a great sanity check for the set of types you are creating in your wrapper. It doesn't matter if you don't know C#, just look at the names of the *.cs
files created. Anything that is named SWIGTYPE_*.cs
represents a type you did not wrap, and a potential future problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With