当前位置: 首页 > 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.lryc.cn/news/613506.html

相关文章:

  • C语言feof函数详解:文件末尾检测的实用工具
  • 【华为机试】113. 路径总和 II
  • 计算机网络1-5:计算机网络的性能指标
  • CSS--:root指定变量,其他元素引用
  • [安卓按键精灵开发工具]本地数据库的初步学习
  • 剑指offer第2版——面试题1:赋值运算符函数
  • CPTS Remote 复现
  • react-router/react-router-dom
  • 深度学习中主要库的使用:(一)pandas,读取 excel 文件,支持主流的 .xlsx/.xls 格式
  • 房产证识别在房产行业的技术实现及应用原理
  • 超高车辆如何影响城市立交隧道安全?预警系统如何应对?
  • 网络基础概念
  • 基于Qt的Live2D模型显示以及控制
  • ora-01658 无法为表空间 users中的段创建initial区
  • RocketMQ架构解析
  • 遥感卫星领域的AI应用
  • Day03 学习git
  • LWIP网络接口管理
  • [airplay2] airplay2简略介绍
  • 二分查找算法,并分析其时间、空间复杂度
  • IIS7.5下的https无法绑定主机头,显示灰色如何处理?
  • 前后端加密传数据实现方案
  • [ java SE ] 多人聊天窗口1.0
  • 强光干扰下裂缝漏检率↓82%!陌讯轻量化模型在道路巡检的落地实践
  • redis--黑马点评--用户签到模块详解
  • JAVA,Maven继承
  • 力扣经典算法篇-46-阶乘后的零(正向步长遍历,逆向步长遍历)
  • Linux Shell为文件添加BOM并自动转换为unix格式
  • 数据分析——Pandas库
  • 什么是 TDengine IDMP?