You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:13:19