From: Marcel B. <br...@fa...> - 2009-12-01 22:10:38
|
Marcel Breuers wrote: > > Dear readers, > > > > I recently started using SWIG to make C++ code available under Matlab by > generating a Java wrapper that can be called in Matlab. > > For basic functionality this works as expected, but boost shared > > pointers are giving me some trouble. > > > > For me it is not clear how to dereference the smart pointer to obtain > > access to the underlying pointer or object. > > Also the smart pointer seems to loose it ability to free memory that is > > no longer referenced. > > > > I was under the impression that boost_shared_ptr.i was going to solve > > all the memory management issues related the smart pointers and that > > this would also create methods to dereference a smart pointer. > > > > Any help and links to examples are appreciated. > > > > Thanks! > > > > ----------------------------------- > > > > Below are samples from my code: > > > > > > I created a dummy C++ class Angle that contains a method to create a new > > Angle object: > > > > Angle::PointerAngle Angle::createAngleSmrt() > > { > > PointerAngle smartPtr( new Angle ); > > return smartPtr; > > } > > > Angle must be a nested class. SWIG doesn't support nested classes, but > the next version has improved support. > > > In the header file I define: > > typedef boost::shared_ptr<Angle> PointerAngle; > > > > In the interface file I include: > > > > %{ > > #include "Angle.h" > > %} > > > > %include "boost_shared_ptr.i" > > %template(SmartPtrAngle) boost::shared_ptr< Angle >; > > > > SWIG_SHARED_PTR(SmartPtrAngle,SmartPtrAngle); > > > SmartPointerAngle isn't a C type, so you have that completely wrong. > Probably you should have > SWIG_SHARED_PTR(SmartPtrAngle, Angle); > and skip the %template statement. > > > Angle::PointerAngle createAngleSmrt(); > > > > You don't show all the code, so I've not idea what PointerAngle is nor > Angle nor inheritance hierarchies. Please see the CHANGES file for an > example of SWIG_SHARED_PTR. > > William ============================= Thanks for your response. I have now included the full code (except for some trivial methods). Could you please explain to me when to use: %template(SmartPtrAngle) boost::shared_ptr< Angle >; and/or SWIG_SHARED_PTR(SmartPtrAngle,SmartPtrAngle); You wrote > SWIG doesn't support nested classes, but the next version has improved support Does this mean I have to introduce a C++ helper class that will only be used to create my working horse class? Thanks in advance. My code (I have removed some trivial functions): ------------------------------------------------ %module AngleSwig %{ #include "Angle.h" %} %include "boost_shared_ptr.i" %template(SmartPtrInt) boost::shared_ptr< int >; %template(SmartPtrAngle) boost::shared_ptr< Angle >; SWIG_SHARED_PTR( SmartPtrAngle , SmartPtrAngle); // make it easy to load native code in Matlab %pragma(java) modulecode=%{ static { try { System.loadLibrary("Angle"); } catch (UnsatisfiedLinkError e) { System.err.println("Native code library failed to load. \n" + e); System.exit(1); } } %} class Angle { public: enum Type { Radians, Degrees }; Angle(); explicit Angle(double i_angle, const Type& i_type = Degrees); Angle(const Angle& i_otherAngle); virtual ~Angle(); double radians() const; double degrees() const; double sin() const; double cos() const; static double degreesToRadians(double i_degrees); static double radiansToDegrees(double i_radians); void reset(); static const double PI; Angle::PointerInt createArray(); Angle::PointerAngle createAngleSmrt(); Angle* createAngle(); private: double m_radians; double m_degrees; double m_sin; double m_cos; void normalize(); }; ------------- HEADER_FILE: ------------- #ifndef DDHK_ANGLE_H #define DDHK_ANGLE_H // STL Includes #include <iostream> #include <vector> #include <boost/shared_ptr.hpp> //mb!! class Angle { public: // Type definitions typedef std::vector<Angle> VectorType; typedef boost::shared_ptr<int> PointerInt; typedef boost::shared_ptr<Angle> PointerAngle; enum Type { Radians, Degrees }; int *arrayTest; // == I want to test how SWIG handles the next three methods == PointerInt createArray(); PointerAngle createAngleSmrt(); Angle* createAngle(); Angle(); explicit Angle(double i_angle, const Type& i_type = Degrees); Angle(const Angle& i_otherAngle); virtual ~Angle(); double radians() const; double degrees() const; static double degreesToRadians(double i_degrees); static double radiansToDegrees(double i_radians); static const double PI; private: double m_radians; double m_degrees; double m_sin; double m_cos; }; #endif // !DDHK_ANGLE_H ----- CPP ----- // Class declaration. #include "Angle.h" // STL Includes #define _USE_MATH_DEFINES #include <math.h> // Pi constant const double Angle::PI = M_PI; Angle::Angle() : m_radians(0.) { normalize(); } Angle::PointerInt Angle::createArray() { arrayTest = new int[50000]; PointerInt smartPtr( arrayTest ); return smartPtr; } Angle::PointerAngle Angle::createAngleSmrt() { PointerAngle smartPtr( new Angle ); return smartPtr; } Angle* Angle::createAngle() { return new Angle; } Angle::Angle(double i_angle, const Type& i_type) { switch (i_type) { default: case Degrees: { m_radians = degreesToRadians(i_angle); break; } case Radians: { m_radians = i_angle; break; } } normalize(); } Angle::Angle(const Angle& i_otherAngle) { m_radians = i_otherAngle.m_radians; normalize(); } Angle::~Angle() { // empty } double Angle::radians() const { return m_radians; } double Angle::degrees() const { return m_degrees; } double Angle::sin() const { return m_sin; } double Angle::degreesToRadians(double i_degrees) { return (i_degrees / 180.) * PI; } double Angle::radiansToDegrees(double i_radians) { return (i_radians / PI) * 180.; } |