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

pybind11无法识别PyObject*为Python对象的原因及解决方法

Pybind11返回PyObject*报错:TypeError: Unregistered type : _object的原因与解决方法

问题场景

尝试用以下C++代码基于pybind11构建扩展库:

#include <pybind11/pybind11.h>

namespace py = pybind11;

PyObject* func() {
    return Py_BuildValue("iii", 1, 2, 3);
}

PYBIND11_MODULE(example, m) {
    m.def("func", &func);
}

运行Python代码调用时:

import example
print(example.func())

触发错误:

TypeError: Unregistered type : _object

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: Unable to convert function return value to a Python type! The signature was
        () -> _object

报错原因

  • pybind11的函数绑定系统默认不识别原始PyObject*类型,它需要明确的类型转换规则,直接返回PyObject*会导致pybind11无法完成类型映射,触发“未注册类型”错误。
  • Py_BuildValue返回的是底层Python对象指针,但pybind11需要将其包装为自身的py::object类型才能正确管理生命周期和类型转换,直接传递原始指针会导致类型不匹配。

解决方法

方法一:用pybind11包装原始PyObject*

修改C++代码,将返回类型改为py::object,并用py::reinterpret_steal接管Py_BuildValue返回对象的所有权:

#include <pybind11/pybind11.h>

namespace py = pybind11;

py::object func() {
    // 接管Python C API创建的对象所有权,让pybind11管理生命周期
    return py::reinterpret_steal<py::object>(Py_BuildValue("iii", 1, 2, 3));
}

PYBIND11_MODULE(example, m) {
    m.def("func", &func);
}

方法二:使用pybind11原生API构造返回值

放弃直接调用Python C API,改用pybind11提供的接口创建Python对象,类型会自动被识别:

#include <pybind11/pybind11.h>
#include <pybind11/tuple.h> // 包含元组构造的头文件

namespace py = pybind11;

py::tuple func() {
    return py::make_tuple(1, 2, 3);
}

PYBIND11_MODULE(example, m) {
    m.def("func", &func);
}

测试验证

修改后重新编译扩展库,运行原Python代码会正常输出:

import example
print(example.func())  # 输出:(1, 2, 3)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:32:33