Я могу получить нормальные обратные вызовы от родного до 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()
Это строится и работает нормально, когда я запускаю простой код Python:
import callback
cb = callback.pyCallback()
cb.execute()
Это прекрасно работает и выводит :: I AM BATMAN
Но это не то, чего я хочу. Я хочу, чтобы функция обратного вызова была частью определенного класса 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'
Как я могу это сделать?? Пожалуйста помоги.
std::function
, см. этот ответ - person DavidW   schedule 14.05.2018ctypedef
указателя функции C. например сделайтеctypedef void (*someFunctionPointer)(char*)
, чтобыsomeFunctionPointer
был указателем на функцию, которая принимает char* и ничего не возвращает. - person DavidW   schedule 01.06.2018