[[開発ノウハウ集]]
2012/12/18 hase wrote
**呼び出しは下記では上手く行かなかった。 [#i7f03051]
 void CallbackFunc() {
 	PyGILState_STATE state = PyGILState_Ensure();
 	if (state == PyGILState_UNLOCKED)
 		PyObject_CallObject(pyCallback, NULL);
 	PyGILState_Release(state);
 }
で上手く行った。
 PyEval_InitThreads();
は最初にEPLoopInit()で呼び出しておく。

2012/12/18 mitake wrote

** 登録 [#zd109807]

下記の関数をPythonから呼べる形で作成します.

(独自関数をPythonから呼べるようにする方法については[[Pythonからアプリケーションの関数を呼び出す]]を参照してください.

 void SetCallbackFunc(PyObject* func) {
 	if (!PyCallable_Check(func)) {
 		PyErr_SetString(PyExc_TypeError, "parameter must be callable");
 		return;
 	}
 	Py_XINCREF(func);
 	Py_XDECREF(callbackFunc);	// 以前のコールバックを捨てる
 	callbackFunc = func;		// 新たなコールバックを記憶
 }


pythonプログラム側では以下のようにして登録します.

 def callback():
 	print("hoge")
 
 # appはSetCallbackFunc関数をメンバに持つアプリケーション
 app.SetCallbackFunc(callback)



** 呼び出し [#s2faec0c]

登録されたコールバックをC++から呼び出す場合は以下のようにします.

 void CallbackFunc() {
 	if (callbackFunc != NULL) {
 		PyEval_InitThreads();
 
 		// GIL(Global Interpreter Lock) を取得する
 		PyGILState_STATE state = PyGILState_Ensure();
 
 		// コールバック関数を呼ぶ
 		PyObject_CallObject(callbackFunc, NULL);
 
 		// GILを解放する
 		PyGILState_Release(state);
 	}
 }