2012-07-20 112 views
4

CPP:升壓Python對象生命週期

#include <boost/python.hpp> 

using namespace boost; 
using namespace boost::python; 

struct Foo 
{ 
    virtual ~Foo() {} 
    virtual void Print() = 0; 
}; 

struct FooWrap : Foo, wrapper<Foo> 
{ 
    void Print() 
    { 
     this->get_override("Print")(); 
    } 
}; 

void ProcessFoo(Foo *obj) { obj->Print(); } 

BOOST_PYTHON_MODULE(hello_ext) 
{ 
    class_<FooWrap, boost::noncopyable>("Foo") 
     .def("Print", pure_virtual(&Foo::Print)); 
    def("ProcessFoo", &ProcessFoo); 
} 

蟒蛇:

import hello_ext 

class NewFoo(hello_ext.Foo): 
    def Print(self): 
     print 'Print call' 

hello_ext.ProcessFoo(NewFoo()) 

一切正常,沒有從ProcessFoo通話Print call文本。但是,我要全部通過指針存儲ProcessFoo,如:

std::vector<Foo*> data; 
void ProcessFoo(Foo *obj) { data.push_back(obj); obj->Print(); } 

後從函數指針退出變得無效,我不能從矢量使用它。使指針的壽命更長的最佳方法是什麼?使用共享指針或告訴python不要刪除對象(如果它刪除它)?

回答

2

如果你想存儲這個指針,你必須增加基礎python對象(PyObject)的引用計數。爲此,你必須實現你的void ProcessFoo(Foo * obj)來獲得一個python對象而不是C++對象,因爲否則boost :: python會在你的adaption中去掉你的python對象,並且你無法控制它的生命期。

如果你這樣做,你也必須做轉換到你的C++類型明確(但與boost :: python這不是很麻煩)。

using namespace boost::python; 
std::vector< std::pair<object, Foo&> > myVec; 

void ProcessFoo(object o) 
{ 
    Foo& x = extract<Foo&>(o); 
    // ... do you add to container here, but remember, to add the object o 
    // too, otherwise the refernce counter will be decremented and the object 
    // may go away. 
    myVec.push_back(std::make_pair(o, x)); 
} 
+0

你有'Foo&'在'std :: pair'嗎? – 2016-03-15 19:56:24

+0

是的,你可以擁有。它不過是一個「指針」。但是您必須確保在刪除後不訪問對象,這是通過增加和存儲引用(對象)來確保的。 – Sven 2016-03-16 09:06:32