使用pybind11封装C++API

背景

爱写c++的小H写了一段时间python之后想到:听说C++程序性能高,能不能把C++和python联动在一起使用呢,于是他开始学习。

很快,他就找到了一个名为pybind11的库,开始在ai的辅助下学习怎么使用。

pybind11

  • 将 C++ 函数、类、数据结构暴露给 Python,让 Python 可以像调用原生函数一样使用它们;
  • 在 C++ 中调用 Python 代码、操作 Python 对象(如列表、字典等)。

本次主要讨论如何在python中使用C++封装的函数、对象等。

使用

首先在环境中引入此库:

python 复制代码
pip install pybind11

给出一个想要封装的C++源程序func.cpp,其中提供了一个函数还有一个类,该有的头文件记得添加进去:

cpp 复制代码
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>  // 支持STL容器
#include <vector>
#include <string>
#include <algorithm>

// 基础函数
int fast_add(int a, int b) {
    int ans=0;
    for(int i=0;i<10000;i++){
        ans+=a+b;
    }
    return ans;
}



// 简单的类示例
class Calculator {
public:
    Calculator(double initial_value = 0.0) : value(initial_value) {}
    
    void add(double x) { value += x; }
    void multiply(double x) { value *= x; }
    double get_value() const { return value; }
    void reset() { value = 0.0; }
    
private:
    double value;
};

接下来就是pybind11的部分了,func.cpp中创建绑定宏:

cpp 复制代码
// pybind11绑定
PYBIND11_MODULE(func, m) {
    m.doc() = "Fast C++ functions for Python";
    
    // 基础函数
    m.def("fast_add", &fast_add, "A function that adds two integers");
    
    // 绑定Calculator类
    pybind11::class_<Calculator>(m, "Calculator")
        .def(pybind11::init<>())
        .def(pybind11::init<double>())
        .def("add", &Calculator::add)
        .def("multiply", &Calculator::multiply)
        .def("get_value", &Calculator::get_value)
        .def("reset", &Calculator::reset);
}

m是一个任意名的形参,首先使用doc填充模块文档,函数的绑定比较简单,就是函数名,引用,相关描述;对于类成员,首先绑定该类,然后绑定方法和成员,这些在python文件引入后都可以通过 对象方法和绑定的名称来调用。

接下来我们使用setup.py来编译这个cpp源代码文件:

python 复制代码
from pybind11.setup_helpers import Pybind11Extension, build_ext
import pybind11
from setuptools import setup

# 定义扩展模块
ext_modules = [
    Pybind11Extension(
        "func",  # 模块名
        ["func.cpp"],  # 源文件
        include_dirs=[
            # pybind11的头文件路径
            pybind11.get_include(),
        ],
        language='c++'
    ),
]

setup(
    name="func-cpp-extension",
    ext_modules=ext_modules,
    cmdclass={"build_ext": build_ext},
    zip_safe=False,
    python_requires=">=3.6",
    packages=[],  # 明确指定不包含Python包
    py_modules=[],  # 明确指定不包含Python模块
)

还是先激活环境,然后输入运行,之后会产生一个对应的pyd(windows上)文件

bash 复制代码
python setup.py build_ext --inplace

再给出一份测试文件,来引入我们编译出的模块是否可以使用

python 复制代码
import func


def main():
    
    result1 = func.fast_add(10, 20)
    print(f"   fast_add(10, 20) = {result1}")
    
    
    # 测试Calculator类
    print("\n3. Calculator类测试:")
    calc = func.Calculator(10.0)
    print(f"   初始值: {calc.get_value()}")
    
    calc.add(5.0)
    print(f"   加5后: {calc.get_value()}")
    
    calc.multiply(2.0)
    print(f"   乘2后: {calc.get_value()}")
    
    calc.reset()
    print(f"   重置后: {calc.get_value()}")
    
    print("\n" + "=" * 50)
    print("所有C++函数调用成功!")


if __name__ == "__main__":
    main()

结语

编译成功之后,小H很高兴,终于感觉自己所学的东西并不会很割裂,也许以后能够组合起来进行运用。

本文章上有什么问题都可以和博主联系。

相关推荐
问天_观心4 分钟前
深入学习Transformer(一)
人工智能·python·深度学习·神经网络·学习·transformer
LabVIEW开发9 分钟前
LabVIEW按段拆分TDMS文件的格式边界与重构
开发语言·数据库·重构·labview·labview知识·labview功能·labview程序
雷帝木木10 分钟前
DVC数据版本控制实战:让训练数据像代码一样可追溯
人工智能·python·深度学习·机器学习
月光船幽幽12 分钟前
五层探针的哲学跃迁
人工智能·python
码匠许师傅17 分钟前
【C++ 面试真题】35. 聊聊 C++ 的万能引用(T&&)和完美转发(std::forward)
java·c++·面试
阿图灵19 分钟前
OpenCV 轮廓与属性:查找轮廓、面积周长、形状拟合与点测试
图像处理·人工智能·python·opencv·计算机视觉·轮廓
asdzx6721 分钟前
使用 Python 为 Excel 添加各类数据验证规则
开发语言·python·excel
Romantic_love_21 分钟前
理解USART真实收发过程
开发语言·stm32·单片机·学习
李可以量化40 分钟前
Redis Client 从了解到精通(二)上:redis-py 高级用法与核心命令实战
前端·数据库·redis·python·缓存·ptrade
撩得Android一次心动44 分钟前
Kotlin 语言【知识点整理3】
java·开发语言·笔记·学习·kotlin