C++ 定义 Callback 类. PyThreadStateLock 保证垮线程调用成功:
#include <Python/Python.h> class Callback { public: Callback(){} virtual ~Callback(){} virtual void call(ObjWithPyCallback& object){} }; class ObjWithPyCallback { public: ObjWithPyCallback(); ~ObjWithPyCallback(); void setCallback(Callback &callback); void call(); private: void NotifyThread(); Callback* callback_; };
class PyThreadStateLock { public: PyThreadStateLock(void) { state = PyGILState_Ensure( ); } ~PyThreadStateLock(void) { PyGILState_Release( state ); } private: PyGILState_STATE state; };
Callback.cpp
ObjWithPyCallback::ObjWithPyCallback() : callback_(NULL) { Py_Initialize(); PyEval_InitThreads(); PyEval_ReleaseLock(); } ObjWithPyCallback::~ObjWithPyCallback() { } void ObjWithPyCallback::setCallback(Callback &callback) { callback_ = &callback; } void ObjWithPyCallback::call() { if ( ! callback_ ) { std::cerr << "No callback is set. "; } else { thread(&ObjWithPyCallback::NotifyThread, this).detach();//call in another thread //callback_->call(*this);//call directly } } void ObjWithPyCallback::NotifyThread() { class PyThreadStateLock PyThreadLock;//fix segmentation fault callback_->call(*this); }
.i 文件中
%module(directors="1") cb %{ #include "Callback.h" %} %feature("director") Callback; %include "Callback.h"
在 python 中调用:
import cb class CB(cb.Callback): def __init__(self): super(CB, self).__init__() def call(self, x): print("Hello from CB!") print(x) o = cb.ObjWithPyCallback() mycb=CB() o.setCallback(mycb) o.call()