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

Boost.Python实现C++嵌入Python时MyCallback类未注册报错如何解决

问题原因

两个报错的核心是你定义的BOOST_PYTHON_MODULE(mylib)绑定代码从未被执行,对应的类、智能指针转换规则都没有注册到当前运行的Python解释器中:

  • 第一个No to_python (by-value) converter found for C++ type: class boost::shared_ptr<class MyCallback>报错:你写的register_ptr_to_python规则绑定在mylib模块下,模块未加载时规则不生效,Boost.Python无法完成C++智能指针到Python对象的转换。
  • 第二个No Python class registered for C++ class class MyCallback报错:改用原始指针传参时,同样因为MyCallback类的绑定信息未注册,Boost.Python找不到对应的Python类映射。
修复步骤
  1. 首先在全局作用域声明模块初始化函数的C导出符号,避免Windows下VC++编译器修改函数名导致找不到入口:
extern "C" __declspec(dllexport) PyObject* PyInit_mylib();
  1. 在Py_Initialize()调用后、导入你的Python业务模块前,先注册并加载你写的mylib绑定模块,触发绑定规则注册:
Py_Initialize();
// 注册自定义模块初始化函数
PyImport_AppendInittab("mylib", &PyInit_mylib);
// 导入模块,执行你写的类、转换器注册代码
boost::python::import("mylib");

// 后面再导入你的业务模块
auto mymodule = boost::python::import("mypackage.mymodule");
  1. 原有传参逻辑无需修改,直接传shared_ptr<MyCallback>对象即可,你写的register_ptr_to_python规则加载后会自动完成转换。
  2. 补充异常处理的空指针判断:PyErr_Fetch返回的错误对象可能为NULL,直接调用extract会触发崩溃,建议先判断pvalue != nullptr再提取错误信息,同时补充错误对象的释放逻辑避免内存泄漏。
完整修改后的C++代码
#include <boost/python.hpp>
#include <boost/make_shared.hpp>
#include <iostream>

using namespace boost;
using namespace boost::python;
using namespace boost::python::api;

// 声明模块初始化函数的C导出符号
extern "C" __declspec(dllexport) PyObject* PyInit_mylib();

class MyCallback {
public:
    void on_order(boost::python::object order) {
        // 测试打印order的name属性
        std::cout << "收到订单:" << extract<std::string>(order.attr("name")) << std::endl;
    }
};

BOOST_PYTHON_MODULE(mylib)
{
    boost::python::class_<MyCallback>("MyCallback")
        .def("on_order", &MyCallback::on_order)
    ;
    boost::python::register_ptr_to_python<boost::shared_ptr<MyCallback>>();
} 

int main() {
    try {
        Py_SetPythonHome(const_cast<wchar_t*>(L"C:/Users/xxxxxx/anaconda3/envs/py36_64"));
        Py_Initialize();

        // 加载自定义绑定模块
        PyImport_AppendInittab("mylib", &PyInit_mylib);
        boost::python::import("mylib");

        auto mymodule = boost::python::import("mypackage.mymodule");
        auto my_class = mymodule.attr("MyClass");
        try {
            auto myCallback = boost::make_shared<MyCallback>();
            auto obj = my_class("John", 123, myCallback);
            obj.attr("send_order")("product1");
        }
        catch (...) {
            PyObject *ptype, *pvalue, *ptraceback;
            PyErr_Fetch(&ptype, &pvalue, &ptraceback);
            if (pvalue) {
                std::wstring strErrorMessage = boost::python::extract<std::wstring>(pvalue);
                // 打印错误信息逻辑自行补充
            }
            // 释放错误对象
            Py_XDECREF(ptype);
            Py_XDECREF(pvalue);
            Py_XDECREF(ptraceback);
        }

        Py_Finalize();
    }
    catch (...) {
        PyObject *ptype, *pvalue, *ptraceback;
        PyErr_Fetch(&ptype, &pvalue, &ptraceback);
        if (pvalue) {
            std::wstring strErrorMessage = boost::python::extract<std::wstring>(pvalue);
        }
        Py_XDECREF(ptype);
        Py_XDECREF(pvalue);
        Py_XDECREF(ptraceback);
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者user1633272

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:24:02