2013-11-21 41 views
3

我想在boost :: python的帮助下将一些C++功能包装到python中。我有一些麻烦让特定的回调机制工作。下面的代码片段说明了什么,我试图做的:在单独的线程中调用boost :: python :: object作为函数

//c++ side 
class LoopClass { 

    public: 
    //some class attributes 

    void call_once(std::function const& fun) const; 
}; 

void callOnce(LoopClass& loop, boost::python::object const& function) { 

    auto fun = [&]() { 
     function(); 
    }; 

    loop->call_once(fun); 
} 

boost::python::class_<LoopClass>("LoopClass") 
    .def("call_once", &callOnce); 


//python side 
def foo(): 
    print "foo"  

loop = LoopClass() 
loop.call_once(foo) 

这里是交易:功能call_once()需要std::function并将其放入队列中。 LoopClass维护一个永久循环,它在一个单独的线程中运行,并在某个点处处理存储的回调函数的队列。要将boost::python::object作为函数来使用,必须明确调用演员操作符。这就是为什么我没有直接换行call_once(),而是编写了小转换函数callOnce(),它将转换操作符调用通过lambda转发。

无论如何,当我尝试运行此代码时,访问boost::python::object失败,出现分段错误。我想在共享线程之间共享python对象并不那么容易。但是,这怎么做呢?

在此先感谢您的帮助!

更新

我试图按照@JanneKarila

的建议,请Non-Python created threads。 - Janne Karila

我想这是找到解决方案的正确点,但不幸的是我无法弄清楚如何应用它。

我试图

void callOnce(LoopClass& loop, boost::python::object const& function) { 

    auto fun = [&]() { 
     PyGILState_STATE gstate; 
     gstate = PyGILState_Ensure(); 

     function(); 

     PyGILState_Release(gstate); 
    }; 

    loop->call_once(fun); 
} 

不工作。我错过了什么或者太愚蠢?

+0

请参阅[非Python创建的主题](http://docs.python.org/2/c-api/init.html#non-python-created-threads)。 –

+0

@JanneKarila感谢您的回复!我更新了我的帖子并添加了我尝试使用的代码。 – thelaui

回答

相关问题