Search code examples
pythonc++swigshared-ptr

swig shared_ptr results in an opaque object


I am trying to SWIG a C++ library to Python. One of the C++ functions returns a shared_ptr. I am successful at producing a Python module but the object returned by that function to Python appears to have no members. Is this a limitation of SWIG's handling of shared_ptr or am I doing something wrong?

This is roughly the structure of my code:

//foo.h
namespace MyNamespace
{
    class Base {};
    template <typename T> class Derived : public Base {};
    std::shared_ptr<Base> make_obj();
}

SWIG:

//foo.i
%module foo
%include <std_shared_ptr.i>

%{
    #define SWIG_FILE_WITH_INIT
    #include "foo.h"
%}

%include "foo.h"
%template(FooA) MyNamespace::Derived< MyNamespace::AAA >;
%template(FooB) MyNamespace::Derived< MyNamespace::BBB >;
%shared_ptr(MyNamespace::Base)
%shared_ptr(FooA)
%shared_ptr(FooB)

Solution

  • I think you've got the order of things a little wrong here. Notice that in all the examples in the shared_ptr documentation they call %shared_ptr before any declaration/definition of that type is seen at all.

    With the caveats commented about the %shared_ptr directive and the FooA/FooB template instances corrected for I believe something like this ought to work for your example.

    //foo.i
    %module foo
    %include <std_shared_ptr.i>
    
    %{
        #define SWIG_FILE_WITH_INIT
        #include "foo.h"
    %}
    
    
    %shared_ptr(MyNamespace::Base)
    %shared_ptr(FooA) // This should probably be MyNamespace::Derived<...>
    %shared_ptr(FooB) // This should probably be the fully qualified C++ type also
    
    %include "foo.h"
    
    %template(FooA) MyNamespace::Derived< MyNamespace::AAA >;
    %template(FooB) MyNamespace::Derived< MyNamespace::BBB >;