Ich habe ein wx.py.Shell.shell Widget, mit dem der Benutzer Python-Code ausführen kann, der mit meinem Programm interagiert. Ich möchte in der Lage sein, eine Funktion, die der Benutzer in diesem Bereich definiert, an meinen C++ - Code (durch den wxswig generierten Wrapper um mein benutzerdefiniertes Widget) zu übergeben und auszuführen.Python Callback von SWIG PyObject_Call Segfault
In meinem C++ Code verwende ich eine std :: function <> Klasse gebundene Funktionen (C++ oder Python) aufzurufen
Also habe ich eine einfache Klasse, die PyObject mit dem Funktionsaufruf Operator zu wickeln. Allerdings bekomme ich einen segfault, wenn ich versuche, das PyObject * aufzurufen.
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);
}
In meinen Versuchen zu finden, was vorging, legte ich eine Reihe von Druckanweisungen. Einer von ihnen gibt den Typnamen und die Referenz aus, um die Zeile vor dem segfault zu zählen. Dies führt zu "Funktion 3", also muss ich davon ausgehen, dass die Funktion noch nicht zerstört wurde.
ich vorbei folgende swig:
void AddOption (std::string name, PyObject *pycallback);
Konstrukt, in dem ich ein PyMenuCallback
ich ratlos bin für das, was die segfault verursacht, irgendwelche Ideen?
aufzunehmen denke ich Sie verletzt habe [Regeldetri] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three), indem kein 'operator =' für 'PyMenuCallback' bereitgestellt wird. Ich bin mir nicht sicher, ob das hier oder nicht das Problem ist, aber es hat sicherlich das Potenzial, Probleme zu verursachen. – Flexo
Ich konnte dies auf meinem Rechner nicht mit einem Testfall reproduzieren. Ich konnte bestätigen, dass "operator =" nicht zufällig verwendet wird, aber der Code funktioniert und hat auch keine Warnungen von valgrind generiert. Können Sie Ihren Testfall etwas erweitern und vereinfachen, indem Sie zum Beispiel "% inline" und "% {%}" verwenden, damit Sie nur eine einzige Schnittstellendatei haben? Z.B. Ich habe Folgendes verwendet: [this] (http://pastebin.com/XYXj3a4p) um zu testen, welche subtilen Unterschiede zu dem haben, was Sie verwenden/verpacken. – Flexo
In der Tat, guter Fang, ich vergaß Operator =. Es wird jedoch im Moment nicht verwendet, aber ich werde es hinzufügen. – Tocs