python使用Pybind11扩展c++的实现

 更新时间:2025年04月30日 09:22:02   作者:Tech Embedded  
Pybind11是一个轻量级的C++库,旨在无缝地将C++代码绑定到Python,本文主要介绍了python使用Pybind11扩展c++的实现,具有一定的参考价值,感兴趣的可以了解一下

Pybind11 是一个轻量级的C++ 库,旨在无缝地将C++代码绑定到Python。它简化了C++ 函数、类和数据结构在Python中使用的过程,使得开发人员可以方便地在Python中调用C++ 代码,同时保留两者的性能优势下面将详细介绍Pybind11的基本概念、安装方法、用法以及示例代码。

Pybind11的基本概念

Pybind11允许C++函数、类和其他对象暴露给Python,使得它们可以在Python中被直接调用。主要功能包括:

  • 暴露C++函数和类给Python。
  • 支持C++的STL容器和数据结构在Python中的使用。
  • 支持C++的异常传递到Python。
  • 允许使用Python对象和函数在C++中。

Pybind11 的优点

  • 兼容性强,支持 Python2.7、Python3.x、PyPy (PyPy2.7 >= 5.7);
  • 可以在 C++ 中使用 lambda 表达式,并在 Python 中使用捕获的变量;
  • 大量使用移动特性,保证数据转移时的性能;
  • 可以很方便地通过 Python buffer protocol 进行数据类型的转移;
  • 可以很方便地对函数进行向量化加速;
  • 支持使用 Python 的切片语法;
  • Pybind11 是 header-only 的,只需要包含头文件即可;
  • 相比于 Boost::Python,生成的二进制文件体积更小;
  • 函数签名通过 constexper 提前计算,进一步减小二进制文件体积;
  • C++ 中的类型可以很容易地进行序列化/反序列化;

Python 以其灵活和易于上手的特点,成为了当下炙手可热的编程语言。然而,动态解释型语言的特点限制了其性能。因此在需要性能的地方,往往使用 C、C++ 等传统高性能语言实现(如 numpy 这种科学计算库),并在 Python 中调用。这就是所谓的混合编程,发挥各自的优势,取长补短。

Pybind11出来以前,Python和C/C++混合编程

Python 的 C-API (Python.h)
SWIG
Python 的 ctypes 模块
Cython
Boost::Python

安装Pybind11

Pybind11可以通过pip轻松安装:

pip install pybind11

或者可以从源码安装:

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

用法示例

1. 暴露简单的C++函数

首先,创建一个简单的C++函数,然后使用Pybind11将其暴露给Python。

C++代码(example.cpp)

#include <pybind11/pybind11.h>

// 简单的C++函数
int add(int i, int j) {
    return i + j;
}

// Pybind11模块定义
PYBIND11_MODULE(example, m) {
    m.def("add", &add, "A function which adds two numbers");
}

编译上面的代码:

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

然后在Python中使用:

import example
print(example.add(2, 3))  # 输出: 5

2. 暴露C++类

Pybind11还可以暴露C++类,并在Python中创建和操作这些类的实例。

C++代码(example.cpp)

#include <pybind11/pybind11.h>

class Pet {
public:
    Pet(const std::string &name) : name(name) {}
    void setName(const std::string &name_) { name = 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);
}

编译代码:

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

在Python中使用:

import example
p = example.Pet("Mittens")
print(p.getName())  # 输出: Mittens
p.setName("Whiskers")
print(p.getName())  # 输出: Whiskers

更多功能

暴露STL容器

Pybind11可以将C++的STL容器(如std::vectorstd::map等)暴露给Python。

C++代码(example.cpp)

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

std::vector<int> get_vector() {
    return {1, 2, 3, 4, 5};
}

PYBIND11_MODULE(example, m) {
    m.def("get_vector", &get_vector);
}

编译代码:

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

在Python中使用:

import example
print(example.get_vector())  # 输出: [1, 2, 3, 4, 5]

异常处理

Pybind11支持将C++中的异常传递到Python,并在Python中进行处理。

C++代码(example.cpp)

#include <pybind11/pybind11.h>

void throws_exception() {
    throw std::runtime_error("An error occurred!");
}

PYBIND11_MODULE(example, m) {
    m.def("throws_exception", &throws_exception);
}

编译代码:

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

在Python中使用:

import example

try:
    example.throws_exception()
except RuntimeError as e:
    print(e)  # 输出: An error occurred!

总结

Pybind11是一个强大且易于使用的工具,允许开发人员将C++ 代码无缝地集成到Python项目中。通过Pybind11,可以高效地暴露C++ 函数、类和数据结构,并在Python中进行调用和操作。其支持STL容器、异常处理等特性,使得它在C++ 与Python交互中表现得非常出色。使用Pybind11,可以充分利用C++的性能优势,同时享受Python的开发便利性。

到此这篇关于python使用Pybind11扩展c++的实现的文章就介绍到这了,更多相关Pybind11扩展c++内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PyTorch手写数字数据集进行多分类

    PyTorch手写数字数据集进行多分类

    这篇文章主要介绍了PyTorch手写数字数据集进行多分类,损失函数采用交叉熵,激活函数采用ReLU,优化器采用带有动量的mini-batchSGD算法,需要的朋友可以参考一下
    2022-03-03
  • Django框架中的对象列表视图使用示例

    Django框架中的对象列表视图使用示例

    这篇文章主要介绍了Django框架中的对象列表视图使用示例,Django是重多Python人气web框架中最为著名的一个,需要的朋友可以参考下
    2015-07-07
  • 如何使用python的pillow库生成图像验证码

    如何使用python的pillow库生成图像验证码

    Pillow库是一个强大的Python图像处理库,用于生成图像验证码,通过初始化图像大小、验证码字符长度和字体大小,生成随机字符串、颜色、线和点,最终生成验证码图像
    2025-01-01
  • 基于Django框架的权限组件rbac实例讲解

    基于Django框架的权限组件rbac实例讲解

    今天小编就为大家分享一篇基于Django框架的权限组件rbac实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • Pygame实现小球躲避实例代码

    Pygame实现小球躲避实例代码

    大家好,本篇文章主要讲的是Pygame实现小球躲避实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • python利用hook技术破解https的实例代码

    python利用hook技术破解https的实例代码

    python利用hook技术破解https的实例代码,需要的朋友可以参考一下
    2013-03-03
  • 关于numpy中eye和identity的区别详解

    关于numpy中eye和identity的区别详解

    今天小编就为大家分享一篇关于numpy中eye和identity的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Python编程中的反模式实例分析

    Python编程中的反模式实例分析

    这篇文章主要介绍了Python编程中的反模式,详细讲述了反模式的害处并以实例形式具体分析了容易造成的易错点,对于Python学习来说具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-12-12
  • 让Python程序定时执行的8种方法整理

    让Python程序定时执行的8种方法整理

    在日常工作中,我们常常会用到需要周期性执行的任务,一种方式是采用 Linux 系统自带的 crond 结合命令行实现,另外一种方式是直接使用Python。本文整理了一下 Python 定时任务的实现方式,希望对大家有所帮助
    2023-01-01
  • Python操作MongoDB增删改查代码示例

    Python操作MongoDB增删改查代码示例

    这篇文章主要介绍了Python操作MongoDB增删改查代码示例,需要的朋友可以参考下
    2022-12-12

最新评论