Macro SWIG_SHARED_PTR with class template

I am using SWIG with generic pointers to create python extensions. My current problem is that the SWIG_SHARED_PTR macro works differently with templates. I will give two examples: one without templates (example) and one with templates (example2).

First I will include the code and at the end I will show the difference in the behavior of the two extensions inside python.

The main problem is that without patterns, shared pointers appear in python as

<example.Derived; proxy of <Swig Object of type 'derived_sptr *' at 0xb772c4b8> >

then when the wrapped class is an instance of the template, appears as

<Swig Object of type 'derived_int_sptr *' at 0xb787e4b8>

I am new to C ++ templates, so it’s quite possible that the problems I am having have nothing to do with SWIG.

No templates (works great)

example.h

 #include <boost/shared_ptr.hpp> #ifndef EXAMPLE_H #define EXAMPLE_H class Base { public: Base(int number1); int get_number1(); virtual int get_number2() = 0; protected: int number1; }; class Derived : public Base { public: Derived(int number1, int number2); int get_number2(); private: int number2; }; typedef boost::shared_ptr<Base> base_sptr; typedef boost::shared_ptr<Derived> derived_sptr; derived_sptr make_derived(int number1, int number2); int get_number1(base_sptr b); #endif 

example.cc

 #include "example.h" Base::Base(int number1) : number1(number1) {} int Base::get_number1() { return number1; } Derived::Derived(int number1, int number2) : Base(number1), number2(number2) {} int Derived::get_number2() { return number2; } derived_sptr make_derived(int number1, int number2) { return derived_sptr(new Derived(number1, number2)); } int get_number1(base_sptr b) { return b->get_number1(); } 

example.i

 %module example %{ #include "example.h" %} %include boost_shared_ptr.i SWIG_SHARED_PTR(base_sptr, Base) SWIG_SHARED_PTR_DERIVED(derived_sptr, Base, Derived) %include example.h 

With templates (does not work)

example2.h

 #include <boost/shared_ptr.hpp> #ifndef EXAMPLE2_H #define EXAMPLE2_H template <typename T> class Base { public: Base(T number1); T get_number1(); virtual T get_number2() = 0; protected: T number1; }; template <typename T> class Derived : public Base<T> { public: Derived(T number1, T number2); T get_number2(); private: T number2; }; typedef Base<int> base_int; typedef Derived<int> derived_int; typedef boost::shared_ptr<base_int> base_int_sptr; typedef boost::shared_ptr<derived_int> derived_int_sptr; derived_int_sptr make_derived_int(int number1, int number2); int get_number1_int(base_int_sptr b); #endif 

example2.cc

 #include "example2.h" template <typename T> Base<T>::Base(T number1) : number1(number1) {} template <typename T> T Base<T>::get_number1() { return number1; } template <typename T> Derived<T>::Derived(T number1, T number2) : Base<T>(number1), number2(number2) {} template <typename T> T Derived<T>::get_number2() { return number2; } template class Base<int>; template class Derived<int>; derived_int_sptr make_derived_int(int number1, int number2) { return derived_int_sptr(new Derived<int>(number1, number2)); } int get_number1_int(base_int_sptr b) { return b->get_number1(); } 

example2.i

 %module example2 %{ #include "example2.h" %} %include boost_shared_ptr.i SWIG_SHARED_PTR(base_int_sptr, base_int) SWIG_SHARED_PTR_DERIVED(derived_int_sptr, base_int, derived_int) %include example.h %template(base_int) Base<int>; %template(derived_int) Derived<int>; 

Difference Example:

 > import example > d = example.make_derived(4, 5) > d > <example.Derived; proxy of <Swig Object of type 'derived_sptr *' at 0xb77327a0> > > d.get_number1() 4 > example.get_number1(d) 4 > import example2 > d = example2.make_derived_int(4, 5) > d <Swig Object of type 'derived_int_sptr *' at 0xb787e4b8> > d.get_number1() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'SwigPyObject' object has no attribute 'get_number1' > example.get_number1_int(d) 4 
0
source share
2 answers

In example2.i line

 SWIG_SHARED_PTR(base_int_sptr, base_int) SWIG_SHARED_PTR_DERIVED(derived_int_sptr, base_int, derived_int) 

should be replaced by

 SWIG_SHARED_PTR(base_int_sptr, Base<int>) SWIG_SHARED_PTR_DERIVED(derived_int_sptr, Base<int>, Derived<int>) 
0
source

SWIG can be very moving about the order in which objects are exposed to it, with its internal type system.

Try moving the %template statements so that they come to your SWIG_SHARED_PTR .

+1
source

All Articles