0Pricing
C++ Academy · 课时

通过 pybind11 从 C++ 调用 Python

使用 pybind11 将 C++ 代码封装为 Python 模块

通过 pybind11 从 C++ 调用 Python 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

为什么使用 pybind11

pybind11 是一个仅包含头文件的库,可以用极少的样板代码为 C++ 代码创建 Python 绑定。SciPy、TensorFlow 和许多其他项目都在使用它。

最小模块

使用 PYBIND11_MODULE 宏,即可在单个文件中定义 Python 模块。

#include <pybind11/pybind11.h>
namespace py = pybind11;

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

PYBIND11_MODULE(mymodule, m) {
    m.def("add", &add, "Add two integers");
}

构建模块

请将其构建为 Python 扩展模块——通常使用 CMake 或 setuptools。

# CMake
find_package(pybind11 REQUIRED)
pybind11_add_module(mymodule mymodule.cpp)

从 Python 中使用

像使用任何 Python 模块一样导入并使用它。

# Python
import mymodule
print(mymodule.add(2, 3))   # 5

公开类

使用 py::class_ 绑定 C++ 类。构造函数、方法和属性都会映射为 Python 中的对应形式。

class Point {
public:
    Point(int x, int y) : x_(x), y_(y) {}
    int x() const { return x_; }
    int y() const { return y_; }
private:
    int x_, y_;
};

PYBIND11_MODULE(geom, m) {
    py::class_<Point>(m, "Point")
        .def(py::init<int, int>())
        .def("x", &Point::x)
        .def("y", &Point::y);
}

类型转换

pybind11 会自动转换常见类型:

  • std::string ↔ Python str
  • std::vector<T> ↔ Python list
  • std::map ↔ Python dict
  • 数值类型 ↔ Python int/float

NumPy 互操作

请将 NumPy 数组作为 py::array_t<T> 传递。访问缓冲区即可执行零拷贝操作。

void scale(py::array_t<double> arr, double factor) {
    auto buf = arr.mutable_unchecked<1>();
    for (size_t i = 0; i < buf.size(); ++i)
        buf(i) *= factor;
}

将 Lambda 用作绑定

如果需要转换参数或包装行为,可以直接绑定 Lambda。

m.def("show", [](const Point& p) {
    return "(" + std::to_string(p.x()) + ", " + std::to_string(p.y()) + ")";
});

释放 GIL

对于耗时较长的 C++ 计算,请释放 GIL,以便其他 Python 线程运行。

m.def("slow", []() {
    py::gil_scoped_release release;
    // expensive C++ work, no Python access
});

性能

pybind11 只增加极少的开销——每次调用通常为几百纳秒。对于非平凡函数,这一开销可以忽略;但对于被频繁调用且执行成本很低的函数,它会产生影响。

替代方案

其他 Python-C++ 桥接工具:

  • Boost.Python——较早出现,开销较大
  • SWIG——支持多种语言
  • nanobind——较新,速度比 pybind11 更快

实际应用场景

pybind11 非常适合:

  • 为 Python 用户封装 C++ 库
  • 使用 C++ 代码加速 Python 中的热点路径
  • 在 C++ 应用和 Python 工具之间共享数值计算内核

快速检查

pybind11 使用哪个宏来声明 Python 模块?

回顾

使用 pybind11 为 Python 封装 C++ 几乎不需要额外工作。请使用 PYBIND11_MODULE 声明模块,使用 m.def 绑定函数,使用 py::class_ 绑定类。内置转换涵盖 STL 类型;NumPy 数组采用零拷贝方式。

常见问题解答

「通过 pybind11 从 C++ 调用 Python」课时是免费的吗?

是的 — 「通过 pybind11 从 C++ 调用 Python」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「通过 pybind11 从 C++ 调用 Python」这节课中我会学到什么?

使用 pybind11 将 C++ 代码封装为 Python 模块 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「通过 pybind11 从 C++ 调用 Python」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Extern C 与 C ABI
  2. 通过 pybind11 从 C++ 调用 Python
  3. 面向 Rust FFI 边界的 C++
  4. 使用 SWIG 生成多语言绑定
← 返回 C++ Academy