enchancements inherit_CPP_classes - cython/cython GitHub Wiki
CEP 529: Allow Python Extension Types to Auto Inherit from C++ Classes
- Status: Open
- Implementation status: Not started
Motivation
Provide support for interfacing with C++ polymorphic frameworks, note this can be done manually by writing a C++ Interface class, however with a small amount of extra information (i.e. if a method is virtual, pure virtual, or not virtual) on C++ class Definition, Cython can autogenerate this interface class and a base extension type that links with the interface class.
Concept
Consider the following C++ Class
class Base {
public:
Base();
~Base();
virtual int pvmethod(int a); // pure virtual
virtual int vmethod(int a) { return a; } // virtual method
int method(int a) { return 2*a+1; } // Normal method
}
and Cython Definition
cdef extern from ...:
cdef cppclass Base:
Base()
pure virtual int pvmethod(int a)
virtual int vmethod(int a)
int method(int a)
we could declare a Extension type as
cdef class PyBase(Base):
pass
Code would be generate along the lines of cpdef functions as follows:
C++ Python aware wrapper class
class pyxBase: Base {
PyObject *py_obj
public:
pyxBase(PyObject *obj): py_obj(obj);
~pyxBase(PyObject *obj);
virtual int pvmethod(int a) { return PyBase_pvmethod(py_obj, a); }
virtual int vmethod(int a) { return PyBase_vmethod(py_obj, a); }
}
and a effective Cython Extenstion type of
cdef class PyBase:
cdef pyxBase* c_ptr
def __cinit__(self):
self.c_ptr = new pyxBase(self)
def __dealloc__(self):
if self.c_ptr:
del self.c_ptr
cpdef int pvmethod(PyBase self, int a): # Exposed to c as int PyBase_pvmethod(PyBase *, int)
raise Error("Can't Call Pure Virtual Method 'pvmethod' of C++ class 'Base'")
cpdef int vmethod(PyBase self, int a): # Exposed to c as int PyBase_vmethod(PyBase *, int)
return self.c_ptr.Base.vmethod(a)
cpdef int method(PyBase self, int a): # Exposed to c as int PyBase_method(PyBase *, int)
return self.c_ptr.method(a)
since cpdef, functions already check if their redefined by python, at c level, this will either call the python redefinition, or attempt to call the method on the base class
self.c_ptr.Base.vmethod(a)
is consider to be represented by the following C code
_p_self.c_ptr.Base::vmethod(a) // _p_self is the point to PyBase, with is the extension type strut
This explicitly calls the Base method not the overload
Then if PyBase is passed to a C++ function expecting Base *, Cyhton would actually pass PyBase.c_ptr, which would be a pointer to a pyxBase Object.
This can be auto-generated as the only dependency is the virtualness of the functions on the base C++ class.