繁体   English   中英

从Cython C调用python函数时的奇怪行为

[英]Strange behaviour when calling python functions from cython c

我有一些C ++代码,一些python代码和一些cython代码。 在C ++中,我有一个执行的异步回调,并且我想执行python代码。

这就是我所做的。 在python中,我编写了一个带有2个参数的函数:

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

然后,在C ++中,我想异步地将此函数“ fn”作为回调。 因此,我创建了一个名为“ PythonCallback”的C ++函数来包装回调。

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时,就会发生问题。 我没有立即收到错误,但是当我尝试仅在python控制台中检查fn时,即如果我只是在控制台中键入fn,则会收到以下错误:

文件“ C:/Users/eric/PycharmProjects/SuperResolution/Startup3dCalibration.py”> 62行,位于fn print(“ hello”)UnicodeDecodeError:'utf-8'编解码器无法解码位置0的字节0xf8:无效>起始字节

如果我再做一次,我会得到他的消息

hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello

最后,如果我第三次这样做,则会得到预期的输出: <function fn at 0x0000000002281048>

我哪里做错了?

再说一遍,在您发布问题之后,解决方案就来了:

所以我意识到使用Py_BuildValue ,在char *字符串和unicode字符串之间存在根本的区别。 因此,只需替换PyObject *args = Py_BuildValue("(ss)", EventName, EventName); PyObject *args = Py_BuildValue("(uu)", EventName, EventName); 解决了我的问题。

我想关于不可转换的unicode的错误最终还是有意义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM