From: Dieter V. <dva...@ax...> - 2010-04-18 00:19:47
|
Hi, i've run into a problem when trying to iterate (in Python) over a proxy of a vector containing a C++ class that is nested in another class. Here's the example: /* InnerOuter.h"/ #include <vector> class Outer { public: class Inner { public: double v_; Inner(double v = 0.0): v_(v) {} }; std::vector<Inner> getSomeInners() { std::vector<Inner> result; result.push_back(Inner(1.0)); result.push_back(Inner(2.0)); return result; }; }; /* InnerOuter.i*/ %module innerouter %include stl.i %feature("autodoc", "1"); %{ #include <vector> #include "InnerOuter.h" %} namespace std { %template(VectorInner) vector<Outer::Inner>; }; class Inner { public: double v_; Inner(double v); }; %{ typedef Outer::Inner Inner; %} class Outer { public: std::vector<Inner> getSomeInners(); }; When i run the following python code: from innerouter import * x = Outer() z = x.getSomeInners() for y in z: print y.v_ #for i in xrange(len(z)): # print z[i].v_ I get this error: Traceback (most recent call last): File "mytest.py", line 7, in <module> print y.v_ AttributeError: 'SwigPyObject' object has no attribute 'v_' swig/python detected a memory leak of type 'unknown', no destructor found. Running the commented code works fine, so i have a workaround, but i thought this might be a helpful test case. I know nested classes are not fully supported, so i can understand if it is nontrivial to resolve this. thanks dieter |
From: William S F. <ws...@fu...> - 2010-04-18 08:01:22
|
Dieter Vandenbussche wrote: > Hi, i've run into a problem when trying to iterate (in Python) over a > proxy of a vector containing a C++ class that is nested in another > class. > > Here's the example: > > /* InnerOuter.h"/ > #include <vector> > > class Outer { > public: > class Inner { > public: > double v_; > Inner(double v = 0.0): v_(v) {} > }; > > std::vector<Inner> getSomeInners() { > std::vector<Inner> result; > result.push_back(Inner(1.0)); > result.push_back(Inner(2.0)); > return result; > }; > }; > > /* InnerOuter.i*/ > %module innerouter > > %include stl.i > > %feature("autodoc", "1"); > > %{ > #include <vector> > #include "InnerOuter.h" > %} > > namespace std { > %template(VectorInner) vector<Outer::Inner>; > }; > > class Inner { > public: > double v_; > Inner(double v); > }; > > %{ > typedef Outer::Inner Inner; > %} > > class Outer { > public: > std::vector<Inner> getSomeInners(); > }; > > When i run the following python code: > from innerouter import * > > x = Outer() > z = x.getSomeInners() > > for y in z: > print y.v_ > > #for i in xrange(len(z)): > # print z[i].v_ > > I get this error: > Traceback (most recent call last): > File "mytest.py", line 7, in <module> > print y.v_ > AttributeError: 'SwigPyObject' object has no attribute 'v_' > swig/python detected a memory leak of type 'unknown', no destructor > found. > > Running the commented code works fine, so i have a workaround, but > i thought this might be a helpful test case. I know nested classes are > not fully supported, so i can understand if it is nontrivial to resolve > this. > You need to put the %template at the end. Also note with swig-2.0.0 due out shortly you can instead use the %nestedworkaround feature as follows: %include stl.i %feature("autodoc", "1"); %{ #include <vector> #include "InnerOuter.h" %} %nestedworkaround Outer::Inner; class Inner { public: double v_; Inner(double v); }; %include "InnerOuter.h" %{ typedef Outer::Inner Inner; %} namespace std { %template(VectorInner) vector<Outer::Inner>; }; William |
From: Dieter V. <dva...@ax...> - 2010-05-22 02:48:45
|
On Sun, 2010-04-18 at 04:01 -0400, William S Fulton wrote: > Dieter Vandenbussche wrote: > > Hi, i've run into a problem when trying to iterate (in Python) over a > > proxy of a vector containing a C++ class that is nested in another > > class. > > > > Here's the example: > > > > /* InnerOuter.h"/ > > #include <vector> > > > > class Outer { > > public: > > class Inner { > > public: > > double v_; > > Inner(double v = 0.0): v_(v) {} > > }; > > > > std::vector<Inner> getSomeInners() { > > std::vector<Inner> result; > > result.push_back(Inner(1.0)); > > result.push_back(Inner(2.0)); > > return result; > > }; > > }; > > > > /* InnerOuter.i*/ > > %module innerouter > > > > %include stl.i > > > > %feature("autodoc", "1"); > > > > %{ > > #include <vector> > > #include "InnerOuter.h" > > %} > > > > namespace std { > > %template(VectorInner) vector<Outer::Inner>; > > }; > > > > class Inner { > > public: > > double v_; > > Inner(double v); > > }; > > > > %{ > > typedef Outer::Inner Inner; > > %} > > > > class Outer { > > public: > > std::vector<Inner> getSomeInners(); > > }; > > > > When i run the following python code: > > from innerouter import * > > > > x = Outer() > > z = x.getSomeInners() > > > > for y in z: > > print y.v_ > > > > #for i in xrange(len(z)): > > # print z[i].v_ > > > > I get this error: > > Traceback (most recent call last): > > File "mytest.py", line 7, in <module> > > print y.v_ > > AttributeError: 'SwigPyObject' object has no attribute 'v_' > > swig/python detected a memory leak of type 'unknown', no destructor > > found. > > > > Running the commented code works fine, so i have a workaround, but > > i thought this might be a helpful test case. I know nested classes are > > not fully supported, so i can understand if it is nontrivial to resolve > > this. > > > You need to put the %template at the end. Also note with swig-2.0.0 due > out shortly you can instead use the %nestedworkaround feature as follows: > > %include stl.i > > %feature("autodoc", "1"); > > %{ > #include <vector> > #include "InnerOuter.h" > %} > > %nestedworkaround Outer::Inner; > > class Inner { > public: > double v_; > Inner(double v); > }; > > %include "InnerOuter.h" > > %{ > typedef Outer::Inner Inner; > %} > > namespace std { > %template(VectorInner) vector<Outer::Inner>; > }; > > William Hi William, you responded to this quite a while ago but i hadn't had time to look back into it, my apologies. While i did find that the %nestedworkaround on swig-2.0 resolved this issue, i was not able to get things to work with swig 1.3.40 by moving the template to the end of the file. I still got the same error message. |