The following C++ code goes off the standard Cython rectangle example, with an arbitrary added "+" operator:
#include "Rectangle.h"
using namespace shapes;
Rectangle::Rectangle(int X0, int Y0, int X1, int Y1)
{
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}
Rectangle::~Rectangle() {}
int Rectangle::getLength()
{
return (x1 - x0);
}
Rectangle operator+(const Rectangle &r1, const Rectangle &r2)
{
return Rectangle(r1.X0 + r2.X0, r1.Y0 + r2.Y0, r1.X1 + r2.X1, r1.Y1 + r2.Y1)
}
This goes with the Cython C++ class definition:
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getLength()
Rectangle operator+(Rectangle) nogil
The only way we've figured out of doing this is by the following Cython code:
cdef class PyRectangle:
cdef Rectangle *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, int x0=0, int y0=0, int x1=0, int y1=0):
if x0 == 0:
self.thisptr = NULL
else:
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def getLength(self):
return self.thisptr.getLength()
def __add__(self, other):
cdef Rectangle rect = deref(self.thisptr) + deref(other.thisptr)
cdef Rectangle* ptr_rect = new Rectangle(rect.x0, rect.y0, rect.x1, rect.y1)
ret = PyRectangle()
ret.thisptr = ptr_rect
return ret
This is not very optimal, since we have an extra copy in __add__
, and the code is not very simple/short either. This is for wrapping an external library, so we can't simply define any new constructors to Rectangle, and we can't rewrite the addition at the Cython level.
We thought that we could simply write something like:
ret = PyRectangle()
deref(ret.thisptr) = deref(self.thisptr) + deref(other.thisptr)
return ret
But this gives the error "Cannot assign to or delete this."
Is there a more preferred way of doing this sort of thing in Cython? The solution we found is not viable in our code.