From: Botos, C. <cb...@ae...> - 2011-11-16 14:32:13
|
On 11/15/11, William S Fulton <ws...@fu...> wrote: > On 15/11/11 15:29, Botos, Christopher wrote: > >Hi, > > > >I have been unsuccessful at getting this somewhat complex file to > >compile (at least it seems complex to me!). > > > >I have a class called DoubleBlocks that has methods returning a > >std::list of type DoubleBlock1 or DoubleBlock2: > > > > std::list<DoubleBlock1> readDoubleBlocks1() const; > > std::list<DoubleBlock2> readDoubleBlock21() const; > > > > > >DoubleBlock1 and DoubleBlock2 are typedefs of templated class > >DataBlock<T>, where T in each case is a typedef of a double, like this.: > > > > typedef double Double1; > > typedef double Double2; > > > > typedef DataBlock<Double1> DoubleBlock1; > > typedef DataBlock<Double2> DoubleBlock2; > > > > > >The .i file portion that deals with this is below. From Python, I need > >to be able to use the methods to get the list of DoubleBlocks, get each > >DoubleBlock from the list, and use DoubleBlock methods to get data from > >them, which are doubles. > > > >When I compile the .cxx, I get the following errors: > > > > DoubleBlocks_wrap.cxx:4126: error: previous definition of âstruct > > swig::traits<NS1::NS2::NS3::DataBlock<double> >â > > DoubleBlocks_wrap.cxx:4332: error: redefinition of âstruct > > swig::traits<std::list<NS1::NS2::NS3::DataBlock<double>, > > std::allocator<NS1::NS2::NS3::DataBlock<double> > > >â > > DoubleBlocks_wrap.cxx:4232: error: previous definition of âstruct > > swig::traits<std::list<NS1::NS2::NS3::DataBlock<double>, > > std::allocator<NS1::NS2::NS3::DataBlock<double> > > >â > > make: *** [DoubleBlocks_wrap.o] Error 1 > > > > > >*However* if I delete (comment out) either of what I labelled the > >Double1 section or Double2 section of the .i file, then the one that > >remained compiles fine and I'm able to manipulate those objects just > >fine in Python. > > > >begin DoubleBlocks.i > >============================================ > >%module DoubleBlocks > >%{ > >#define SWIG_FILE_WITH_INIT > >#include "DataBlock.h" > >#include "DoubleBlock1.h" > >#include "DoubleBlock2.h" > >using namespace NS1::NS2::NS3; > >%} > > > >%include "std_list.i" > >%include "DataBlock.h" > > > >//------------------------------------------------------------------------- > >// Double1 > >// std::list<DoubleBlock1> readDoubleBlocks1() const; > >namespace NS1 { > >namespace NS2 { > >namespace NS3 { > >typedef NS1::NS2::NS3::DataBlock<NS1::NS2::NS3::Double> DoubleBlock1; > >typedef std::list<NS1::NS2::NS3::DataBlock<NS1::NS2::NS3::Double> > > >DoubleBlock1_List; > >}}} > > > >%typemap(out) NS1::NS2::NS3::Double1& { $result = > >PyFloat_FromDouble((double) *$1); } > >%template(DoubleBlock1) NS1::NS2::NS3::DataBlock<NS1::NS2::NS3::Double1>; > >%template(DoubleBlock1_List) std::list<NS1::NS2::NS3::DoubleBlock1>; > > > >//------------------------------------------------------------------------- > >// Double2 > >// std::list<DoubleBlock2> readDoubleBlocks2() const; > >namespace NS1 { > >namespace NS2 { > >namespace NS3 { > >typedef NS1::NS2::NS3::DataBlock<NS1::NS2::NS3::Double2> DoubleBlock2; > >typedef std::list<NS1::NS2::NS3::DataBlock<NS1::NS2::NS3::DoubleBlock2> > > > DoubleBlock2List; > >}}} > > > >%typemap(out) NS1::NS2::NS3::Double2& { $result = > >PyFloat_FromDouble((double) *$1); } > >%template(DoubleBlock2) NS1::NS2::NS3::DataBlock<NS1::NS2::NS3::Double2>; > >%template(DoubleBlock2List) std::list<NS1::NS2::NS3::DoubleBlock2>; > Avoid using typedefs for the template parameters in %template. I've some fixes in progress so this will work better, but for now you probably need: > > %template(DoubleBlock2) NS1::NS2::NS3::DataBlock< double >; > %template(DoubleBlock2List) std::list< double >; > > which if I've read your code correctly is correct as all that verbiage is actually a double! > > William > Thanks so much for your reply, William. I realize everything comes down to doubles, but the C++ code uses typedefs everywhere. I unfortunately have no control over any of the C++ implementation. If I understand your suggestion correctly, then "%template(DoubleBlock2List) std::list< double >" should actually be "%template(DoubleBlock2List) std::list<NS1::NS2::NS3::DataBlock<std::list< double > >" If I do that, then when I run the code (AND I comment everything about Double1) I get a runtime error when Python tries to get the DoubleBlock2 from the list: ... datablock = datablock[0] TypeError: 'SwigPyObject' object is unsubscriptable swig/python detected a memory leak of type 'NS1::NS2::NS3::DoubleBlock2List *', no destructor found. But then if I return to using the typedefs in the %template parameters it runs fine. BUT then, again, if I uncomment the Double1 code, I get back the compile error. Chris > > > |