开发者

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

开发者 https://www.devze.com 2025-05-01 09:17 出处:网络 作者: Tech
目录Pybind11的基本概念Pybind11 的优点Pybind11出来以前,python和C/C++混合编程安装Pybind11用法示例1. 暴露简单的C++函数2. 暴露C++类更多功能暴露STL容器异常处理总结Pybind11 是一个轻量级的C++ 库,旨在无缝地
目录
  • Pybind11的基本概念
  • Pybind11 的优点
  • Pybind11出来以前,python和C/C++混合编程
  • 安装Pybind11
  • 用法示例
    • 1. 暴露简单的C++函数
    • 2. 暴露C++类
  • 更多功能
    • 暴露STL容器
    • 异常处理
  • 总结

    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/pybphpind11.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 -androidm 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的开发便利性。

    到此这篇关于pyjavascriptthon使用Pybind11扩展c++的实现的文章就介绍到这了,更多相关Pybind11扩展c++内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号