У меня есть виджет wx.py.Shell.shell, который позволяет пользователю выполнять код Python, взаимодействующий с моей программой. Я хочу иметь возможность передать функцию, которую пользователь определяет в этом пространстве, в мой код C++ (через сгенерированную wxswig оболочку вокруг моего пользовательского виджета) и выполнить ее.
В моем коде C++ я использую класс std::function ‹> для вызова связанных функций (C++ или Python)
Поэтому я создал простой класс, чтобы обернуть PyObject оператором вызова функции. Однако я получаю segfault, когда пытаюсь вызвать 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);
}
В своих попытках выяснить, что происходит, я поместил кучу печатных утверждений. Один из которых печатает имя типа и количество ссылок на строку перед segfault. Это приводит к «функции 3», поэтому я должен предположить, что функция еще не уничтожена.
Я передаю следующее swig:
void AddOption (std::string name, PyObject *pycallback);
В котором я создаю PyMenuCallback
Я в недоумении, что вызывает segfault, есть идеи?
operator=
дляPyMenuCallback
. Я не уверен, проблема в этом или нет, но это, безусловно, может вызвать проблемы. - person Flexo   schedule 11.07.2012operator=
используется не случайно, но код работал и не выдавал никаких предупреждений от valgrind. Можете ли вы немного расширить и упростить свой тестовый пример, используя%inline
и%{%}
, чтобы у вас был только один файл интерфейса? Например. Я использовал: это, чтобы проверить, что может иметь небольшие отличия от того, что вы используете/обертываете. - person Flexo   schedule 11.07.2012