私はwx.py.Shell.shellウィジェットを持っています。これにより、ユーザーは私のプログラムと対話するPythonコードを実行できます。ユーザーがこのスペースで定義した関数をC++コードに(カスタムウィジェットのwxswigで生成されたラッパーを介して)渡して実行できるようにしたいと思います。
私のC++コードでは、std :: function <>クラスを使用して、バインドされた関数(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);
}
何が起こっているのかを見つけるために、私はたくさんの印刷ステートメントを入れました。そのうちの1つは、タイプ名と参照カウントをセグメンテーション違反の前の行に出力します。これにより「関数3」が生成されるため、関数はまだ破棄されていないと想定する必要があります。
私はswigに以下を渡します:
void AddOption (std::string name, PyObject *pycallback);
ここでPyMenuCallbackを作成します
何がセグメンテーション違反を引き起こしているのか途方に暮れています、何かアイデアはありますか?