使用pybind11重写Python内置print函数后程序退出崩溃求助
问题
使用pybind11将Python嵌入C应用时,尝试从C层重写Python内置的print函数,代码如下:
mBuiltinsMod = py::module::import("builtins"); mBuiltinsMod.attr("print") = py::cpp_function([](py::object msg) { std::cout << msg.cast<std::string>(); });
这段代码成功将print函数的输出转向cout,但程序退出时会崩溃,崩溃发生在pybind11/embed.h的finalize_interpreter函数中:
void finalize_interpreter() { // ... if (internals_ptr_ptr) { // 崩溃位置 delete *internals_ptr_ptr; *internals_ptr_ptr = nullptr; } }
重写print函数时还需要执行哪些步骤来修复该崩溃问题?
解决方案
崩溃根源是重写builtins.print后,未妥善恢复原始函数,导致Python解释器退出时内置模块状态异常,引发对象销毁顺序冲突。可通过以下步骤修复:
保存并恢复原始
print函数
在重写print前先保存原始函数的引用,在Python解释器销毁前务必恢复原函数,避免内置模块的状态被篡改后引发销毁错误:// 初始化阶段:保存原始print函数 py::module builtins_mod = py::module::import("builtins"); py::object original_print = builtins_mod.attr("print"); // 重写print函数 builtins_mod.attr("print") = py::cpp_function([](py::object msg) { std::cout << msg.cast<std::string>(); }); // 程序退出前、解释器finalize前:恢复原始print builtins_mod.attr("print") = original_print;确保自定义函数的生命周期安全
避免py::cpp_function对象被提前销毁,若lambda捕获了外部变量,需保证这些变量在Python解释器运行期间始终有效;必要时使用py::keep_alive维护对象引用计数,防止提前析构。规范解释器的初始化与销毁流程
所有自定义绑定的修改(如重写内置函数)必须在finalize_interpreter()调用前完成清理,恢复Python内置模块的原始状态,确保解释器销毁时的内部状态一致。
内容的提问来源于stack exchange,提问作者Dess
相关产品推荐
相关产品推荐

