user4979733
user4979733

Reputation: 3411

Cython: copy constructor

I have the following C++ class interface that I'm trying to cythonize.

class NetInfo
{
public:
  NetInfo();
  NetInfo(NetInfo const& rhs);
  virtual ~NetInfo();
  void swap(NetInfo& rhs) throw();
  NetInfo& operator=(NetInfo rhs);
  ...
}

This is what I have so far. I am not totally sure how to implement the copy constructor. I haven't seen any examples in the Cython user guide. The issue in copy construction is how to get a NetInfo object from 'other' which is a PyNetInfo object. Any ideas?

cdef extern from 'NetInfo.h' namespace '...':
    cdef cppclass NetInfo:
        NetInfo() except +
        NetInfo(NetInfo&) except +
        operator=(NetInfo) except +
        ...

cdef class PyNetInfo:
    cdef NetInfo* thisptr

def __cinit__(self, PyNetInfo other=None):
    cdef PyNetInfo ostr
    if other and type(other) is PyNetInfo:
        ostr = <PyNetInfo> other
        self.thisptr = ostr.thisptr
    else:
        self.thisptr = new NetInfo()
    def __dealloc__(self):
        del self.thisptr

Upvotes: 1

Views: 758

Answers (1)

user4979733
user4979733

Reputation: 3411

Cython has special operators to handle C++'s *, &, ++, -- to be compatible with Python syntax. Hence, they need to be cimported and used. See http://cython.org/docs/0.24/src/userguide/wrapping_CPlusPlus.html#c-operators-not-compatible-with-python-syntax

from cython.operator cimport dereference as deref

cdef class PyNetInfo:
    cdef NetInfo* thisptr

    def __cinit__(self, other=None):
        cdef PyNetInfo ostr
        if other and type(other) is PyNetInfo:
            ostr = <PyNetInfo> other
            self.thisptr = new NetInfo(deref(ostr.thisptr))
        else:
            self.thisptr = new NetInfo()
    def __dealloc__(self):
        del self.thisptr

Here is the output:

Type "help", "copyright", "credits" or "license" for more information.
>>> import netinfo
>>> a = netinfo.PyNetInfo()
>>> b = netinfo.PyNetInfo()
>>> a.setNetName('i am a')
>>> b.setNetName('i am b')
>>> c = netinfo.PyNetInfo(b) <-- copy construction.
>>> a.getNetName()
'i am a'
>>> b.getNetName()
'i am b'
>>> c.getNetName()     <--- c == b
'i am b'
>>> c.setNetName('i am c') <-- c is updated
>>> a.getNetName()
'i am a'
>>> b.getNetName()     <-- b is not changed
'i am b'
>>> c.getNetName()     <-- c is changed
'i am c'
>>> exit()

Upvotes: 2

Related Questions