Return c++ object (not a pointer preferably) in cython
<p>I have two classes (let's assume the most simple ones, implementation is not important). My <code>defs.pxd</code> file (with cython defs) looks like this:</p>

<pre><code>cdef extern from "A.hpp":
  cdef cppclass A:
    A() except +

cdef extern from "B.hpp":
  cdef cppclass B:
    B() except +
    A func ()
</code></pre>

<p>My <code>pyx</code> file (with python defs) looks like this:</p>

<pre><code>from cython.operator cimport dereference as deref
from libcpp.memory cimport shared_ptr

cimport defs

cdef class A:
    cdef shared_ptr[cquacker_defs.A] _this

    @staticmethod
    cdef inline A _from_this(shared_ptr[cquacker_defs.A] _this):
        cdef A result = A.__new__(A)
        result._this = _this
        return result

    def __init__(self):
        self._this.reset(new cquacker_defs.A())

cdef class B:
    cdef shared_ptr[cquacker_defs.B] _this

    @staticmethod
    cdef inline B _from_this(shared_ptr[cquacker_defs.B] _this):
        cdef B result = B.__new__(B)
        result._this = _this
        return result

    def __init__(self):
        self._this.reset(new cquacker_defs.B())

    def func(self):
      return deref(self._this).func()
</code></pre>

<p>The thing is that I cannot return non-python object from Python. Actually, I don't want to change my c++ code to return pointer instead of new object (because there are many functions like that). Now it gives me the error:</p>

<pre><code>Cannot convert 'B' to Python object
</code></pre>

<p>How can I return one python object holding internal c++ object from another one's method in python? If I can only do that after some c++ changes, I want the most elegant solution, if possible.</p>

<p>Your issue is that your wrapper class requires a pointer (to a <code>new</code> allocated object) but your function returns an C++ object on the stack. To solve this you have to copy or move the object from the stack.</p>

<p>First ensure that your C++ class <code>A</code> has a working copy or move constructor. A move constructor is better if you're c++ class contains large members. Wrap this is Cython like so:</p>

<pre><code>cdef extern from "A.hpp":
  cdef cppclass A:
    A() except +
    A(const A&amp;) except +
    # or A(A&amp;&amp;) except +
</code></pre>

<p>(Don't tell Cython about both a copy constructor and a move constructor - it gets confused! C++ finds the right one when it's compiled anyway).</p>

<p>Then, in <code>func</code> use your copy/move constructor with <code>new</code> to pass to your python wrapper:</p>

<pre><code>def func(self):
      return A._from_this(new cquacker_defs.A(self._this.func()))
</code></pre>

python c++ cython