python脚本完成后清理所有c ++对象

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 ++对象?

Har*_*iri 1

您可以将 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)