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

pybind11&C++环境下如何实现vector引用传递并同步数据到Python侧

问题根因

当前问题是pybind11默认的std::vector类型转换规则导致的:当Python侧的list传入绑定的C接口时,pybind11会拷贝生成一个独立的C std::vector对象,C++侧修改的是这个拷贝后的对象,不会同步到Python侧原来的list上。


方案1:修改接口为返回vector(代码改动最小)

直接把C++的calc方法调整为返回填充好的std::vector<double>,pybind11会自动把返回的vector转为Python的list,不需要修改绑定逻辑,改动量最小。

C++代码调整

class Calculator
{
public:
    Calculator() {}
    // 改返回值为std::vector<double>,去掉入参里的results
    static std::vector<double> calc(const Setup& setup) {
        std::vector<double> results;
        // 原有填充results的逻辑保持不变
        return results;
    }
};

// 绑定部分无需修改,保持原有逻辑即可

Python侧调用调整

results = a_calculator.calc(a_setup)

该方案优点是无需处理类型转换细节,代码量最少,适合对性能要求不高的场景。


方案2:用numpy数组实现零拷贝引用传递(性能最优)

如果数据量较大,不想产生拷贝开销,可以直接使用pybind11的numpy数组接口,直接操作Python侧numpy数组的内存,改动很小。

C++代码调整

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

class Calculator
{
public:
    Calculator() {}
    // 把results参数改为py::array_t<double>类型接收numpy数组
    static void calc(const Setup& setup, py::array_t<double> results) {
        // 获取numpy数组的可写指针
        auto buf = results.mutable_unchecked<1>();
        // 直接操作内存填充数据,示例如下
        for (py::ssize_t i = 0; i < buf.shape(0); i++) {
            buf(i) = 待填充的数值;
        }
    }
};

// 绑定逻辑保持原有内容不变即可

Python侧调用调整

# 提前初始化对应长度、类型为float64的numpy数组
results = np.zeros(所需数据长度, dtype=np.float64)
a_calculator.calc(a_setup, results)
# 此时results已被C++侧修改完成,可直接使用

该方案为零拷贝实现,性能远高于方案1,适合处理大数据量场景。


可选方案:绑定std::vector实现引用传递

如果必须保留C++侧std::vector<double>&的参数类型,可以在绑定代码中增加std::vector的绑定声明:

PYBIND11_MODULE(one_calculator, m) {
    // 增加该行绑定std::vector<double>为Python侧的VectorDouble类型
    py::bind_vector<std::vector<double>>(m, "VectorDouble");

    // 原有绑定逻辑保持不变
    m.doc() = "pybind11 one_calculator plugin";
    py::class_<Setup>(m, "Setup")
        .def(py::init<int>());
    py::class_<Calculator>(m, "Calculator")
        .def(py::init<>())
        .def("calc", &Calculator::calc);
}

Python侧调用时使用绑定的VectorDouble类型即可:

from one_calculator import Setup, Calculator, VectorDouble

results = VectorDouble()
a_calculator.calc(a_setup, results)
# 可根据需要转为原生list或numpy数组
list_results = list(results)
np_results = np.array(results)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:27:01