Я могу получить нормальные обратные вызовы от нативного к Cython.
Но как мне установить функцию-член для обратного вызова в Cython.
Мой sampleCallback.h
файл:
namespace mango {
class sampleCalls {
public:
typedef void (*Callback)(char *name);
sampleCalls(Callback method, char *name);
void execute();
private:
Callback _method;
char *_key;
}; }
И мой sampleCallback.cpp
файл содержит простую реализацию:
namespace mango {
sampleCalls::sampleCalls(Callback method, char *name) {
_method = method;
_key = name;
};
void sampleCalls::execute()
{
return _method(_key);
};
}
Теперь я написал очень простую оболочку для Cython 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строит и отлично работает, когда я запускаю простой код на Python:
import callback
cb = callback.pyCallback()
cb.execute()
Это прекрасно работает и выводит: * Я Бэтмен
Но это не то, что яхочу.Я хочу, чтобы функция обратного вызова была частью определенного Cython класса, поэтому я реализовал этот класс примерно так:
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"
Это, конечно, не работает, поскольку прототип обратного вызова не совпадает.
Что такое правильный способ сделать это?
Я также попробовал std :: bind примерно так:
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")
Это тоже не работает.Ошибка ::
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'
Как я могу это сделать ??Пожалуйста помоги.