Pybind11教程:从零开始打造 Python 的 C++ 小帮手

参考官网文档:https://pybind11.readthedocs.io/en/stable/index.html

一、Pybind11 是什么?

想象你在 Python 里写了个计算器,但跑得太慢,想用 C++ 提速,又不想完全抛弃 Python。Pybind11 就像一座桥,把 C++ 的高性能代码“嫁接”到 Python 里。你可以用 Python 调用 C++ 函数,就像请了个跑得飞快的帮手来干活。

  • 主要功能
    1. 绑定函数:把 C++ 函数变成 Python 能用的。
    2. 传递数据:Python 和 C++ 之间无缝传值。
    3. 扩展模块:生成一个 Python 模块,导入就用。
二、准备工作
  1. 安装 Pybind11

    • 需要 C++ 编译器(Windows 用 MSVC,Mac/Linux 用 gcc/clang)。
    • 用 pip 安装 Pybind11:
    • 检查安装:命令行输入 python -m pybind11 --includes,会返回 Pybind11 的头文件路径(比如 -I/…/pybind11/include)。
  2. 安装 Python 和 CMake

    • 确保有 Python(3.x 推荐)。
    • 装 CMake(用来生成项目):pip install cmake 或官网下载。
  3. 写个简单 C++ 文件: 新建 example.cpp:

int add(int a, int b) { 
	return a + b; 
}

我们要让 Python 能调用这个 add 函数。

三、基础绑定:让 Python 用上 C++
  1. 改写 C++ 文件: 把 example.cpp 改成这样:
#include <pybind11/pybind11.h>

int add(int a, int b) {
    return a + b;
}

PYBIND11_MODULE(example, m) {
    m.doc() = "一个简单的加法模块"; // 模块描述
    m.def("add", &add, "加两个数", pybind11::arg("a"), pybind11::arg("b"));
}
  • #include <pybind11/pybind11.h>:引入 Pybind11 的魔法工具。
  • PYBIND11_MODULE(example, m):定义一个 Python 模块叫 example,m 是模块对象。
  • m.def:把 C++ 的 add 函数绑定到 Python,起名叫 add,还加了参数名和描述。
  1. 编译成模块

    • 新建 setup.py:
from setuptools import setup
from pybind11.setup_helpers import Pybind11Extension

ext_modules = [
    Pybind11Extension(
        "example",  # 模块名
        ["example.cpp"],  # 源文件
    ),
]
setup(
    name="example",
    ext_modules=ext_modules,
)
  • 命令行运行:
    python setup.py build_ext --inplace

  • 成功后会生成一个 example.xxx.pyd(Windows)或 example.xxx.so(Linux/Mac)。

  1. 在 Python 中试试
import example
print(example.add(3, 4))  # 输出 7
print(example.__doc__)   # 输出 “一个简单的加法模块”
  1. 怎么回事?

    • Pybind11 把 C++ 代码编译成了 Python 的扩展模块,你可以像导入普通库一样用它。
    • 比喻:就像把 C++ 的“快车”装进 Python 的“车库”,随时开出来用。
四、进阶玩法:玩转数据和功能
1. 绑定带默认参数的函数

改 example.cpp:

#include <pybind11/pybind11.h>

int add(int a, int b = 10) {
    return a + b;
}

PYBIND11_MODULE(example, m) {
    m.def("add", &add, "加两个数", pybind11::arg("a"), pybind11::arg("b") = 10);
}
  • 重新编译后:
import example
print(example.add(5))     # 输出 15(5 + 10)
print(example.add(5, 3))  # 输出 8(5 + 3)
2. 处理 Python 列表

让 C++ 处理 Python 传来的列表:

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

std::vector<int> double_list(std::vector<int> lst) {
    for (int& x : lst) x *= 2;
    return lst;
}

PYBIND11_MODULE(example, m) {
    m.def("double_list", &double_list, "把列表每个数翻倍");
}
  • 编译后:
 import example 
 print(example.double_list([1, 2, 3])) # 输出 [2, 4, 6]
3. 绑定类

定义一个 C++ 类给 Python 用:

#include <pybind11/pybind11.h>

class Pet {
public:
    Pet(const std::string& name) : name(name) {}
    void setName(const std::string& new_name) { name = new_name; }
    std::string getName() const { return name; }
private:
    std::string name;
};

PYBIND11_MODULE(example, m) {
    pybind11::class_<Pet>(m, "Pet")
        .def(pybind11::init<const std::string&>())  // 构造函数
        .def("setName", &Pet::setName)              // 方法
        .def("getName", &Pet::getName);             // 方法
}
  • 编译后:
import example 
p = example.Pet("小狗") 
print(p.getName()) # 输出 “小狗” 
p.setName("小猫") 
print(p.getName()) # 输出 “小猫”
五、更酷的功能:优化和调试
  1. 提速

    • Pybind11 默认很快,但可以用 C++ 的优化编译选项(比如 -O3):
      python setup.py build_ext --inplace -DCMAKE_CXX_FLAGS="-O3"
  2. 调试

    • 出错了?加 --verbose 查看编译详情:
      python setup.py build_ext --inplace --verbose
六、实战练习

试试这个任务:

  1. 写个 C++ 文件 math_ops.cpp:
#include <pybind11/pybind11.h>

int multiply(int a, int b = 2) {
    return a * b;
}

PYBIND11_MODULE(math_ops, m) {
    m.def("multiply", &multiply, "乘法", pybind11::arg("a"), pybind11::arg("b") = 2);
}
  1. 用 Pybind11 编译成模块。

  2. 在 Python 中测试:

import math_ops 
print(math_ops.multiply(5)) # 输出 10 
print(math_ops.multiply(5, 3)) # 输出 15
七、注意事项
  1. 编译环境
    • 确保 C++ 编译器版本匹配(比如 MSVC 2019+)。
  2. 依赖问题
    • 如果用了其他 C++ 库,setup.py 里要加 libraries=[“库名”]。
  3. 跨平台
    • 编译出的模块只能在同系统用,换系统要重新编译。
八、总结:Pybind11 的绑定法则
  • 基础绑定:用 m.def 把 C++ 函数给 Python。
  • 高级用法:绑定类(class_)、处理列表(std::vector)。
  • 优化调试:加编译选项提速,用 --verbose 查错。
  • 打包:用 setup.py 生成模块,导入即用。

通过这个教程,你应该能轻松用 Pybind11 把 C++ 的“超能力”带到 Python 里,像搭积木一样简单!如果有问题欢迎私信交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值