我正在为获取对象所有权的第 3 方库创建绑定,因此我尝试使用FAQ中记录的 auto_ptr 。
这是我包装的两个类的示例:
typedef std::auto_ptr<Panel> PanelAutoPtr;
class NewPanelCallback {
public:
NewPanelCallback(object c) { callable = c; }
PanelAutoPtr operator() (wxWindow* parent) {
object result = callable(boost::ref(parent));
return extract<PanelAutoPtr>(result);
}
private:
object callable;
};
void Factory_register_method(Factory* f,
const wxString& id,
boost::python::object callable)
{
f->registerFactoryMethod(id, NewPanelCallback(callable));
}
class_<Factory, boost::noncopyable>("Factory", no_init)
.def("get", &Factory::get, return_value_policy<reference_existing_object>());
.def("register", &Factory_register_method);
class_<Panel, std::auto_ptr<Panel>, bases<wxWindow>, boost::noncopyable)
("Panel", init<wxWindow*, int, const wxString&>()>;
我的应用程序允许插件开发人员将 Python 函数注册为用于创建小部件的工厂方法。一个例子:
class MyPanel(shell.Panel):
def __init__(self, parent, id, name):
super().__init__(parent, id, name)
def create_panel(parent):
return MyPanel(parent, -1, "Test")
shell.Factory.get().register("some_panel", create_panel)
现在,我的问题是,当我的程序调用 NewPanelCallback 仿函数(在 C++ 中)时,面板对象在调用运算符返回之前被删除!就像提取函数调用没有从结果对象中获取指针的所有权一样。
void create_a_panel(wxFrame* frm, NewPanelCallback& cb) {
PanelAutoPtr p = cb(frm);
frm->Add(p.get());
p.release();
}
有什么提示吗?
解决方案
我终于通过不使用“提取”来解决这个问题。这是我的新 NewPanelCallback():
class NewPanelItemCallback {
public:
NewPanelItemCallback(object c) { callable = c; }
PanelAutoPtr operator() (wxWindow* parent) {
return call<Shell::PanelAutoPtr>(callable.ptr(), boost::ref(parent));
}
private:
object callable;
};
我不太确定为什么这行得通,而另一种方式则行不通。对此的任何评论将不胜感激。