当前位置: 首页 > news >正文

pybind11 的应用

pybind11 是一个轻量级的 C++ 库,用于将 C++ 代码暴露给 Python 调用,或者反过来在 C++ 中调用 Python 代码。它比传统的 Boost.Python 更简洁高效,适用于现代 C++(C++11 及以上)。以下是 pybind11 的基本使用方法:


1. 安装 pybind11

可以通过 pip 安装:

pip install pybind11

或者从源码安装(推荐):

git clone https://github.com/pybind/pybind11.git
cd pybind11
mkdir build && cd build
cmake ..
make install

2. 基本用法:C++ 暴露给 Python

示例 1:简单函数绑定

// example.cpp
#include <pybind11/pybind11.h>int add(int a, int b) {return a + b;
}PYBIND11_MODULE(example, m) {m.def("add", &add, "A function that adds two numbers");
}
编译(Linux/macOS)
c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
编译(Windows, MSVC)
cl /EHsc /LD /I C:\path\to\Python\include /I C:\path\to\pybind11\include example.cpp /link /LIBPATH:C:\path\to\Python\libs
在 Python 中调用
import example
print(example.add(2, 3))  # 输出 5

示例 2:绑定 C++ 类

// example_class.cpp
#include <pybind11/pybind11.h>class MyClass {
public:MyClass(int value) : value_(value) {}void setValue(int v) { value_ = v; }int getValue() const { return value_; }
private:int value_;
};PYBIND11_MODULE(example_class, m) {pybind11::class_<MyClass>(m, "MyClass").def(pybind11::init<int>()).def("setValue", &MyClass::setValue).def("getValue", &MyClass::getValue);
}
编译(同上)
c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example_class.cpp -o example_class$(python3-config --extension-suffix)
在 Python 中调用
import example_class
obj = example_class.MyClass(10)
print(obj.getValue())  # 输出 10
obj.setValue(20)
print(obj.getValue())  # 输出 20

3. Python 调用 C++ 的高级用法

(1) 支持 NumPy 数组(pybind11/numpy.h

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>namespace py = pybind11;py::array_t<double> add_arrays(py::array_t<double> a, py::array_t<double> b) {py::buffer_info a_buf = a.request(), b_buf = b.request();auto result = py::array_t<double>(a_buf.size);py::buffer_info res_buf = result.request();double *a_ptr = static_cast<double *>(a_buf.ptr);double *b_ptr = static_cast<double *>(b_buf.ptr);double *res_ptr = static_cast<double *>(res_buf.ptr);for (size_t i = 0; i < a_buf.size; i++) {res_ptr[i] = a_ptr[i] + b_ptr[i];}return result;
}PYBIND11_MODULE(numpy_example, m) {m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
}
Python 调用
import numpy as np
import numpy_examplea = np.array([1.0, 2.0, 3.0])
b = np.array([4.0, 5.0, 6.0])
print(numpy_example.add_arrays(a, b))  # 输出 [5.0, 7.0, 9.0]

(2) 在 C++ 中调用 Python 代码

#include <pybind11/embed.h>  // 必须包含这个头文件
#include <iostream>namespace py = pybind11;int main() {py::scoped_interpreter guard{};  // 启动 Python 解释器py::module sys = py::module::import("sys");py::print(sys.attr("path"));  // 打印 Python 路径py::module math = py::module::import("math");float root = math.attr("sqrt")(2.0).cast<float>();std::cout << "sqrt(2) = " << root << std::endl;return 0;
}
编译 & 运行
g++ -std=c++11 -I/usr/include/python3.8 -lpython3.8 call_python.cpp -o call_python
./call_python
sqrt(2) = 1.41421

4. 使用 CMake 管理项目

cmake_minimum_required(VERSION 3.4)
project(example)find_package(pybind11 REQUIRED)  # 需要 pybind11 已安装pybind11_add_module(example example.cpp)  # 编译为 Python 模块
编译
mkdir build && cd build
cmake ..
make

生成的 .so 或 .pyd 文件可以直接在 Python 中导入。


5. 常见问题

(1) 如何传递 STL 容器?

pybind11 自动支持 std::vectorstd::map 等:

#include <pybind11/stl.h>  // 必须包含这个头文件std::vector<int> process_vec(const std::vector<int>& v) {std::vector<int> result;for (int x : v) result.push_back(x * 2);return result;
}PYBIND11_MODULE(stl_example, m) {m.def("process_vec", &process_vec);
}

Python 调用:

import stl_example
print(stl_example.process_vec([1, 2, 3]))  # 输出 [2, 4, 6]

(2) 如何暴露 C++ 异常?

#include <stdexcept>void risky_func(int x) {if (x < 0) throw std::runtime_error("x must be >= 0");
}PYBIND11_MODULE(exception_example, m) {m.def("risky_func", &risky_func);
}

Python 调用:

import exception_example
try:exception_example.risky_func(-1)
except RuntimeError as e:print(e)  # 输出 "x must be >= 0"

总结

功能方法
C++ 函数暴露给 Pythonm.def("func_name", &func)
C++ 类暴露给 Pythonpybind11::class_<MyClass>(m, "MyClass")
支持 NumPy#include <pybind11/numpy.h>
C++ 调用 Pythonpy::scoped_interpreter{} + py::module::import
STL 容器支持#include <pybind11/stl.h>
异常处理直接抛出 std::exception

pybind11 是 C++/Python 互操作的高效工具,适用于高性能计算、机器学习等领域。

http://www.dtcms.com/a/320120.html

相关文章:

  • (Python)Python爬虫入门教程:从零开始学习网页抓取(爬虫教学)(Python教学)
  • 腾讯iOA技术指南:实现数据防泄漏与高级威胁防护
  • Spark Memory 内存设计的核心组件、对比Flink内存配置
  • langchain入门笔记02:几个实际应用
  • 生信分析进阶16 - 可准确有效地检测血浆 ccf-mtDNA 突变的分析方法
  • DrissionPage实战案例:小红书旅游数据爬取
  • 串口转ADC/PWM 串口转I2C 串口转GPIO工具
  • c++20--std::format
  • 工业相机使用 YOLOv8深度学习模型 及 OpenCV 实现目标检测简单介绍
  • 计算机视觉CS231n学习(4)
  • jmeter要如何做接口测试?
  • python源码是如何运行起来的
  • HTTPS是如何确保网站安全性的?
  • 【Apache Olingo】全面深入分析报告-OData
  • 使用Ollama本地部署DeepSeek、GPT等大模型
  • C++模拟法超超超详细指南
  • 连续最高天数的销售额(动态规划)
  • 如何让keil编译生成bin文件与反汇编文件?
  • 机器学习:线性回归
  • Win10桌面从默认C盘改到D盘
  • 小红书开源多模态视觉语言模型DOTS-VLM1
  • 深入剖析React框架原理:从虚拟DOM到Fiber架构
  • PCA9541调试记录
  • 软考中级【网络工程师】第6版教材 第2章 数据通信基础(下)
  • ansible 操作家族(ansible_os_family)信息
  • 网页中 MetaMask 钱包钱包交互核心功能详解
  • Redis缓存数据库深度剖析
  • ESXI7.0添加标准交换机过程
  • 通过CNN、LSTM、CNN-LSTM及SSA-CNN-LSTM模型对数据进行预测,并进行全面的性能对比与可视化分析
  • [Oracle] DECODE()函数