来自 C++ 的回调 python 函数,对象被破坏
Posted
技术标签:
【中文标题】来自 C++ 的回调 python 函数,对象被破坏【英文标题】:callback python function from C++ , object destructed 【发布时间】:2019-09-12 14:41:02 【问题描述】:我执行一段python代码生成C++对象并回调一个python函数,然后把这个对象返回给python,为什么对象被破坏了?
我使用boost python来包装我的C++程序并从python创建一个对话框。然后当点击一个按钮时,回调一个python函数,将这个对象指针返回到这个函数,但是对象成员数据似乎全部清除了
class MyObj
public:
OtherThing();
ConnectFunc(boost::python::object callbackfun)m_pyCallbackFunc=callbackfun;
//some operation will call below function
DoSomething()m_pyCallbackFunc(this)
private:
boost::python::object m_pyCallbackfunc;
vector<int> m_vecData;
def callback(myobject):
#call my object functions again
myobject.Otherthing()
//first generate C++ object by python ,such as
obj=MyObj
obj.ConnectFunc(callback)....
一切顺利,但执行OtherThing()函数时,成员数据 m_vecData 已被清除。我发现当调用python函数“回调”时, MyObj会调用销毁函数,所以数据已经被清除了
任何人都可以帮助我如何避免它,我想保留它吗?或者有人给我个好主意
【问题讨论】:
【参考方案1】:当您执行以下操作时:
DoSomething()m_pyCallbackFunc(this)
您的m_pyCallbackFunc
从这个副本接收一个新的代理对象,这意味着它接收到的对象不是接收到的DoSomething
对象。假设你有以下类:
class Foo
public:
boost::python::object bar()
return boost::python::object(boost::python::ptr(this));
;
您导出的内容如下:
boost::python::class_<Foo>("Foo")
.def(
"bar",
&Foo::bar
);
假设foo.bar()
会返回foo
是安全的,但事实并非如此。以下将引发断言错误:
foo = Foo()
assert foo is foo.bar()
因为返回的是一个新的代理对象。如果你想将同一个对象传回 Python,你必须声明你的类,比如 Boost know it has back references,或者我最喜欢的;将您的方法声明为静态并提取您的实例:
class Foo
public:
static boost::python::object bar(boost::python::object self)
Foo &pSelf = boost::python::extract<Foo &>(self);
return self;
;
现在上面的代码将不再引发断言错误,因为返回的对象与接收到的对象相同。基本上,您的析构函数被调用是因为代理对象创建的副本超出范围并被释放。
【讨论】:
以上是关于来自 C++ 的回调 python 函数,对象被破坏的主要内容,如果未能解决你的问题,请参考以下文章
通过 Boost Python 将 Python 函数转换为 C++,用作回调
Pybind11:为啥来自 Python 的异步调用不能在 C++ 中正确执行回调?