title: pybind11: return c++ class (with an existing python binding) to python
body: <p>I am trying to create a wrapper for a c++ method that returns a c++ class(vtkPolyData) which comes from an external c++ library (vtk). The same library has python binding available which is already installed in my python environment. How do you tell pybind that the c++ class (vtkPolydata) and its python variant are the same?  </p>
  
  <p>I tried to use this <a href="https://gitlab.kitware.com/cmb/smtk/blob/master/smtk/extension/vtk/pybind11/PybindVTKTypeCaster.h" rel="nofollow noreferrer">custom type caster macro</a>. but I get TypeError: <code>Unable to convert function return value to a Python type! The signature was : (self: Versa3dLib.skeletonizer, offset distance: float) -&gt; vtkPolyData</code>  </p>
  
  <p>which is confusing since it looks like the conversion maps to the correct type but python is unable to interpret it. So I am not sure what's wrong since I don't see anything wrong with the macro either. I noticed that in python vtkPolyData has type <code>vtkCommonDataModelPython.vtkPolyData</code>. is that why the conversion is not done correctly?  </p>
  
  <pre><code>#include "skeletonizer.h"
  #include &lt;pybind11/pybind11.h&gt;
  #include &lt;pybind11/stl.h&gt;
  #include "PybindVTKTypeCaster.h"
  #include &lt;vtkSmartPointer.h&gt;
  
  namespace py = pybind11;
  
  PYBIND11_VTK_TYPECASTER(vtkPolyData)
  PYBIND11_DECLARE_HOLDER_TYPE(T, vtkSmartPointer&lt;T&gt;);
  
  namespace pybind11 { namespace detail {
      template &lt;typename T&gt;
      struct holder_helper&lt;vtkSmartPointer&lt;T&gt;&gt; { // &lt;-- specialization
          static const T *get(const vtkSmartPointer&lt;T&gt; &amp;p) { return p.GetPointer(); }
      };
  }}
  
  PYBIND11_MODULE(Versa3dLib, m)
  {
      py::class_&lt;skeletonizer&gt;(m, "skeletonizer")
          .def(py::init&lt;vtkPolyData *&gt;())
          .def("get_offset", &amp;skeletonizer::get_offset,
               "return vtkPolyData offset",
               py::arg("offset distance"));
  }
  </code></pre>
  
  <p>Skeletonizer</p>
  
  <pre><code>#ifndef SKELETONIZER_H
  #define SKELETONIZER_H
  
  #include &lt;vtkPolyData.h&gt;
  #include &lt;vector&gt;
  #include &lt;vtkSmartPointer.h&gt;
  
  
  using namespace std;
  
  class skeletonizer
  {
      public:
          skeletonizer(vtkPolyData* data);
          vtkSmartPointer&lt;vtkPolyData&gt; get_offset(double dist);
  };
  
  #endif
  </code></pre>
  
  <p>skeletonizer cpp</p>
  
  <pre><code>#include "skeletonizer.h"
  
  
  skeletonizer::skeletonizer(vtkPolyData* data)
  {
  };
  
  vtkSmartPointer&lt;vtkPolyData&gt; skeletonizer::get_offset(double dist)
  {
      vtkSmartPointer&lt;vtkPolyData&gt; offsets = vtkSmartPointer&lt;vtkPolyData&gt;::New();
  
      return offsets;
  };
  </code></pre>