gpt4 book ai didi

c++ - 来自 SWIG PyObject_Call 段错误的 Python 回调

转载 作者:太空狗 更新时间:2023-10-29 20:28:38 28 4
gpt4 key购买 nike

我有一个 wx.py.Shell.shell 小部件,它允许用户执行与我的程序交互的 python 代码。我希望能够将用户在此空间中定义的函数传递到我的 C++ 代码(通过 wxswig 生成的围绕我的自定义小部件的包装器)并执行它。

在我的 C++ 代码中,我使用 std::function <> 类来调用绑定(bind)函数(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”,因此我必须假设该功能尚未被破坏。

我将以下内容传递给 swig:

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

我在其中构建了一个 PyMenuCallback

我不知道是什么导致了段错误,有什么想法吗?

最佳答案

由于调用 python 回调的 C++ 在 wxWidget 中,并且 swig 包装器是由特殊的 wxPython swig(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"

关于c++ - 来自 SWIG PyObject_Call 段错误的 Python 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11435760/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com