2013-11-21 37 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

回答

相關問題