I have a C++ class with a virtual method:
//C++
class A
{
public:
A() {};
virtual int override_me(int a) {return 2*a;};
int calc
The solution is somewhat complicated, but it is possible. There is a fully working example here: https://bitbucket.org/chadrik/cy-cxxfwk/overview
Here is an overview of the technique:
Create a specialized subclass of class A
whose purpose will be to interact with a cython extension:
// created by cython when providing 'public api' keywords:
#include "mycymodule_api.h"
class CyABase : public A
{
public:
PyObject *m_obj;
CyABase(PyObject *obj);
virtual ~CyABase();
virtual int override_me(int a);
};
The constructor takes a python object, which is the instance of our cython extension:
CyABase::CyABase(PyObject *obj) :
m_obj(obj)
{
// provided by "mycymodule_api.h"
if (import_mycymodule()) {
} else {
Py_XINCREF(this->m_obj);
}
}
CyABase::~CyABase()
{
Py_XDECREF(this->m_obj);
}
Create an extension of this subclass in cython, implementing all non-virtual methods in the standard fashion
cdef class A:
cdef CyABase* thisptr
def __init__(self):
self.thisptr = new CyABase(
self)
#------- non-virutal methods --------
def calculate(self):
return self.thisptr.calculate()
Create virtual and pure virtual methods as public api
functions, that take as arguments the extension instance, the method arguments, and an error pointer:
cdef public api int cy_call_override_me(object self, int a, int *error):
try:
func = self.override_me
except AttributeError:
error[0] = 1
# not sure what to do about return value here...
else:
error[0] = 0
return func(a)
Utilize these function in your c++ intermediate like this:
int
CyABase::override_me(int a)
{
if (this->m_obj) {
int error;
// call a virtual overload, if it exists
int result = cy_call_override_me(this->m_obj, a, &error);
if (error)
// call parent method
result = A::override_me(i);
return result;
}
// throw error?
return 0;
}
I quickly adapted my code to your example, so there could be mistakes. Take a look at the full example in the repository and it should answer most of your questions. Feel free to fork it and add your own experiments, it's far from complete!