从cython c调用python函数时的奇怪行为 我有一些C++代码,一些python代码和一些Cython代码。 在C++中,我有一个异步回调,它被执行,并且我希望执行Python代码。

从cython c调用python函数时的奇怪行为 我有一些C++代码,一些python代码和一些Cython代码。 在C++中,我有一个异步回调,它被执行,并且我希望执行Python代码。,python,c++,callback,python-c-api,Python,C++,Callback,Python C Api,这就是我所做的。 在python中,我编写了一个包含两个参数的函数: def fn(x,y): print("hello") print(x) print(y) 然后,在C++中,我想异步调用这个函数“FN”作为回调。 所以我创建了一个C++函数,叫做“Python CalbBead”来包装回调。 class PythonCallback{ public: PyObject *_pyfunc; PythonCallback(PyObject *pyfu

这就是我所做的。 在python中,我编写了一个包含两个参数的函数:

def fn(x,y):
    print("hello")
    print(x)
    print(y)

然后,在C++中,我想异步调用这个函数“FN”作为回调。 所以我创建了一个C++函数,叫做“Python CalbBead”来包装回调。

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
传递给它。i、 e.
instance=CallbackInformation(fn)

当我调用python回调函数
fn
时,就会出现问题。 我没有立即得到错误,但是当我尝试在python控制台中检查
fn
时,即如果我只是在控制台中键入fn,我会得到以下错误:

文件“C:/Users/eric/PycharmProjects/SuperResolution/Startup3dCalibration.py”>第62行,在fn中 打印(“你好”) UnicodeDecodeError:“utf-8”编解码器无法解码位置0中的字节0xf8:无效>开始字节

如果我再这样做, 我收到他的信息了

Hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello

最后,如果我第三次这样做,我会得到预期的输出:


我哪里出错了?

再一次,在你发布问题后,解决方案马上出现:

因此,我意识到使用
Py_BuildValue
,字符*字符串和unicode字符串之间有着根本的区别。因此,只需替换
PyObject*args=Py_BuildValue(“(ss)”,EventName,EventName)带有
PyObject*args=Py\u BuildValue(“(uu)”,EventName,EventName)修复了我的问题

我想关于不可转换的unicode的错误最终是有道理的