У меня есть код C++, код Python и код Cython. В C++ у меня есть асинхронный обратный вызов, который выполняется, и я хочу, чтобы код Python выполнялся.
Вот что я сделал. На питоне я написал функцию, которая принимала 2 параметра:
def fn(x,y):
print("hello")
print(x)
print(y)
Затем в C++ я хотел вызвать эту функцию "fn" асинхронно в качестве обратного вызова. Поэтому я создал функцию C++ под названием «PythonCallback», чтобы обернуть обратный вызов.
class PythonCallback{
public:
PyObject *_pyfunc;
PythonCallback(PyObject *pyfunc);
void presentCallback(_bstr_t EventName, BYTE* CallbackData);
void addCallbackToGUID( PyObject* Py_GUID );
}
//Constructor
PythonCallback::PythonCallback(PyObject *pyfunc){
if( PyCallable_Check(pyfunc)){
Py_INCREF(pyfunc);
_pyfunc = pyfunc;
}else{
throw -1;
}
};
void PythonCallback::presentCallback(_bstr_t EventName, BYTE* pCallbackData)
{
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
EventData* evData = (EventData*)pCallbackData;
PyObject *args = Py_BuildValue("(ss)", EventName, EventName);
const wchar_t* wstring(EventName);
PyObject_CallObject(_pyfunc, args );
std::wstring w;
w.append(EventName);
// PyObject_CallFunction( _pyfunc, "(ss)", wstring, wstring);
// PyObject_CallFunction( _pyfunc, "(ss)", w.c_str(),w.c_str());
// PyObject_CallFunction( _pyfunc, "(s)", w.c_str() );
// PyObject_CallFunction( _pyfunc, "" );
// PyObject_CallFunction( _pyfunc, "ss", wstring, wstring );
PyGILState_Release(gstate);
};
И все это склеено с помощью Cython. В Cython я создал класс, который будет отправлять функцию python на C++.
cdef class CallbackInformation:
cdef PythonCallback *thisptr
def __cinit__(self, object func):
self.thisptr = new PythonCallback(func)
# temp = PythonCallback(func)
def __dealloc__(self):
del self.thisptr
def addCallbackToGUID(self,guid):
self.thisptr.addCallbackToGUID(guid)
Итак, что бы я сделал, это создать новый экземпляр CallbackInformation
и передать ему fn
. то есть instance = CallbackInformation(fn)
Проблема возникает, когда я вызываю функцию обратного вызова python fn
. Я не получаю немедленную ошибку, но когда я пытаюсь просто проверить fn
в консоли Python, т.е. если я просто наберу fn в консоли, я получаю следующую ошибку:
Файл «C:/Users/eric/PycharmProjects/SuperResolution/Startup3dCalibration.py»,> строка 62, в fn print («привет») UnicodeDecodeError: кодек «utf-8» не может декодировать байт 0xf8 в позиции 0: недопустимо> стартовый байт
если я сделаю это снова, я получу его сообщение
привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет.
и, наконец, если я сделаю это в третий раз, я получу ожидаемый результат: <function fn at 0x0000000002281048>
Где я неправ?