I am able to get normal callbacks from native to Cython.
But, how do i set a member function to be callback in cython.
My sampleCallback.h
file is :
namespace mango {
class sampleCalls {
public:
typedef void (*Callback)(char *name);
sampleCalls(Callback method, char *name);
void execute();
private:
Callback _method;
char *_key;
}; }
And my sampleCallback.cpp
file contains simple implementation :
namespace mango {
sampleCalls::sampleCalls(Callback method, char *name) {
_method = method;
_key = name;
};
void sampleCalls::execute()
{
return _method(_key);
};
}
Now i have written a very simple cython wrapper callback.pyx
:
ctypedef void (*Callback)(char *name)
cdef extern from "sampleCallback.h" namespace "mango" :
cdef cppclass sampleCalls:
sampleCalls(Callback method, char *name)
void execute()
cdef void callbackCY(char* name):
print "I AM ", name
cdef class pyCallback:
cdef sampleCalls* sc
def __init__(self):
self.sc = new sampleCalls(callbackCY, "BATMAN")
def execute(self):
self.sc.execute()
This builds and works fine when i run a simple python code :
import callback
cb = callback.pyCallback()
cb.execute()
This works just fine and outputs :: I AM BATMAN
But this is not what i want. I want the callback function to be a part of the cython defined class, so i implemented the class something like this :
cdef class pyCallback:
cdef sampleCalls* sc
def __init__(self):
self.sc = new sampleCalls(cb, "BATMAN")
def execute(self):
self.sc.execute()
cdef void cb(self, char* name):
print name, " WINS"
This does not work of course as callback prototype do not match.
WHAT IS THE PROPER WAY TO DO IT?
I also tried std::bind something like this ::
cdef place1 "std::placeholder1"
cdef bind_py "std::bind"
cdef class pyCallback:
cdef sampleCalls* sc
def __init__(self):
self.sc = new sampleCalls(bind_py(self.cb, self, place1), "BATMAN")
This does not work either. The error ::
Error compiling Cython file:
------------------------------------------------------------
...
cdef class pyCallback:
cdef sampleCalls* sc
def __init__(self):
self.sc = new sampleCalls(bind_py(self.cb, self, place1), "BATMAN")
^
------------------------------------------------------------
callback.pyx:19:40: Cannot convert 'void (pyCallback, char *)' to Python object
Error compiling Cython file:
------------------------------------------------------------
...
cdef class pyCallback:
cdef sampleCalls* sc
def __init__(self):
self.sc = new sampleCalls(bind_py(self.cb, self, place1), "BATMAN")
^
------------------------------------------------------------
callback.pyx:19:35: Cannot convert Python object to 'Callback'
How can i get this done ?? Please help.