Python的回调从呷PyObject_Call段错误(Python Callback from S

2019-09-19 08:17发布

我有一个wx.py.Shell.shell小部件,它可以让与我的程序交互用户执行Python代码。 我希望能够通过用户定义在这个空间我的C ++代码(通过在我的自定义插件的wxswig生成的包装)的功能,并执行它。

在我的C ++代码我使用一个std ::函数<>类调用结合功能(C ++或Python)

所以,我创建了一个简单的类函数调用操作符来包装的PyObject。 不过,我得到一个段错误,当我尝试调用的PyObject *。

class PyMenuCallback
{
    PyObject *Func;
public:
    PyMenuCallback(const PyMenuCallback &op2);
    PyMenuCallback(PyObject *func);
    ~PyMenuCallback ();

    void operator() (int id);
};
/////////////////////////////////////////////////////////
PyMenuCallback::PyMenuCallback(PyObject *func)
    : Func(func)
{
    Py_XINCREF (Func);
    if(!PyCallable_Check(Func))
        cout << "Not a Callable Callback." << endl; //Throw an exception or something
}

PyMenuCallback::PyMenuCallback(const PyMenuCallback &op2)
    : Func (op2.Func)
{
    Py_XINCREF (Func);
    if(!PyCallable_Check(Func))
        cout << "Not a Callable Callback." << endl;
}

PyMenuCallback::~PyMenuCallback()
{
    Py_XDECREF (Func);
}

void PyMenuCallback::operator() (int id)
{
    cout << "Calling Callback" << endl;
    if (Func == 0 || Func == Py_None || !PyCallable_Check(Func))
        return;
    cout << "Building Args" << endl;   
    PyObject *arglist = Py_BuildValue ("(i)",id);
    cout << "Func: " << Func->ob_type->tp_name << " " << Func->ob_refcnt << endl;
    PyObject *result = PyObject_Call(Func,arglist,0); //<<<<<---SEGFAULTS HERE
    cout << "Executed" << endl;
    Py_DECREF(arglist);
    Py_XDECREF(result);
}

在我试图找到发生了什么事情,我放了一堆打印报表。 其中一个打印类型名称和引用计数的段错误前行。 这将导致“功能3”,所以我必须承担的功能还没有被破坏。

我通过以下痛饮:

void AddOption (std::string name, PyObject *pycallback);

我在其中构造一个PyMenuCallback

我在对什么引起的段错误,任何想法亏损?

Answer 1:

由于C ++调用蟒蛇回调是一个wxWidget内,并通过特殊的wxPython痛饮生成的包装痛饮(wxswig?)周围有一个函数调用所需的某些线程保护...

固定运营商应该是这样的

void PyMenuCallback::operator() (int id)
{
    cout << "Calling Callback" << endl;
    if (Func == 0 || Func == Py_None || !PyCallable_Check(Func))
        return;
    cout << "Building Args" << endl;   
    PyObject *arglist = Py_BuildValue ("(i)",id);
    cout << "Built: " << arglist << endl;
    cout << "Func: " << Func->ob_type->tp_name << " " << Func->ob_refcnt << endl;

    wxPyBlock_t blocked = wxPyBeginBlockThreads(); //Anti-WxSwig 

    PyObject *result = PyObject_Call(Func,arglist,0);

    wxPyEndBlockThreads(blocked);


    cout << "Executed" << endl;
    Py_XDECREF(arglist);
    Py_XDECREF(result);
}

确保包括

#include "wx/wxPython/wxPython.h"
#include "wx/wxPython/wxPython_int.h"


文章来源: Python Callback from SWIG PyObject_Call Segfault