And*_* R. 5 c++ python boost boost-python
我有一个应用程序,实现python解释器,自定义python模块,导出类.示例c ++类可能如下所示:
class MyClass {
MyClass() { cout << "created" << endl; }
~MyClass() { cout << "destroyed" << endl; }
};
Run Code Online (Sandbox Code Playgroud)
执行python脚本的代码如下所示:
namespace bp = boost::python;
bp::dict dict;
try {
dict = bp::dict(bp::import("__main__").attr("__dict__"));
bp::exec_file(filename, dict, dict);
} catch (bp::error_already_set &) {
// dict.clear()
PyErr_Print();
PyErr_Clear();
}
Run Code Online (Sandbox Code Playgroud)
问题是,在脚本被异常终止后,不会立即销毁从python代码创建的c ++对象.例如,简单的脚本运行两次:
import MyModule
myobj = MyModule.MyClass()
assert False
Run Code Online (Sandbox Code Playgroud)
输出我得到(A):
// script launched first time
created
// script finished
// script launched second time
created
destroyed
// script finished
// Py_Finalize() is called
destroyed
Run Code Online (Sandbox Code Playgroud)
输出我想要(B):
// script launched first time
created
// script finished
destroyed
// script launched second time
created
// script finished
destroyed
// Py_Finalize() is called
Run Code Online (Sandbox Code Playgroud)
现在,有趣的部分.如果我们取消注释// dict.clear(),行为开始根据脚本结构而不同.对于上面提到的python片段,我得到了输出B(正如预期的那样),但我仍然得到A脚本,如:
import MyModule
def main():
myobj = MyModule.MyClass()
assert False
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
如何正确删除从python创建的c ++对象?
您可以将 C++ 对象的所有权授予 python。
请检查下面的示例,它可能适合您。
另请查看此链接以更多地了解通话政策。
C++代码:
class MyClass {
public:
MyClass() { cout << "created" << endl; }
~MyClass() { cout << "destroyed" << endl; }
};
MyClass* get_objectof_MyClass(){
return new MyClass();
}
BOOST_PYTHON_MODULE(MyModule)
{
class_<MyClass>("MyClass");
def("get_objectof_MyClass", get_objectof_MyClass, return_value_policy<manage_new_object>());
//using manage_new_object we are giving ownership to python side and python will clean it up when out of scope.
}
Run Code Online (Sandbox Code Playgroud)
Python端代码:
import MyModule
def main():
myobj = MyModule.get_objectof_MyClass()
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
输出:
created
destroyed
Run Code Online (Sandbox Code Playgroud)