Python调用C++之PyBind11

以下为授权转载的一盎司科技公众号文章


PyBind11是一个轻量级的C++库,主要用于创建现有C++代码的Python绑定,使用了很多C++新特性。

下面将简单介绍使用PyBind11将C++类提供给Python使用的基本步骤,关于PyBind11的详细内容可参考官方文档(https://pybind11.readthedocs.io/en/stable/)。

示例代码地址:

GitHub地址:https://github.com/iounce/python-cpp-demo

Gitee地址:https://gitee.com/iounce_admin/python-cpp-demo

环境

  • Windows操作系统:Windows10(21H2,19044.1766)

  • C++开发环境:Visual Studio 2022社区版

  • Python:3.10.4

  • PyBind11:2.11.1

安装PyBind11

直接执行命令pip install pybind11安装即可:

图片

编写C++文件

这里编写一个模板函数和一个继承类的示例,具体如下:

图片

图片

编写PyBind11文件

需要按照PyBind11文件的格式来编写,模板类需要指定具体类型才能正常使用。继承类则需要定义基类,并增加函数的说明,可以自定义Python中使用的函数名。具体如下:

图片

编写setup.py文件

编写setup.py文件主要是为了导出Python包,需要指定包名,引用路径,实现文件等。具体如下:

图片

生成Python包

直接使用命令python setup.py build编译生成最终包即可,最终会在build目录生成一个pyd为后缀的Python包文件:

图片

图片

图片

编写Python测试程序

简单起见,先将生成的Python包文件pybind11_demo.cp310-win_amd64.pyd(环境不同生成文件名可能有差异)拷贝到当前目录,然后编写测试程序main.py并执行:

图片

PyBind11可以使用C++里面的很多写法,就是格式比较有特点,调用C++函数或类都很方便,也是一种不错的选择。

<think>好的,我现在需要回答用户关于如何使用pybind11Python调用C++类的问题。用户已经提供了三个相关的引用内容,我需要结合这些引用,特别是引用[3],来构建一个清晰的示例。首先,我应该回顾pybind11的基本用法,确保自己理解如何绑定C++类到Python。 根据引用[3],用户提到需要创建一个C++类,比如DataParser,它有一些方法如mkdir_savefold()和work(),并且构造函数需要传入一个文件路径。所以,我需要构造一个类似的示例,展示如何用pybind11绑定这个类。 首先,我需要编写C++类的头文件和实现文件。例如,定义一个MyClass类,构造函数接受一个字符串参数,然后有若干方法,比如getName和processData。然后,在绑定代码中使用PYBIND11_MODULE来导出这个类,包括构造函数和方法。 接下来,编译这部分代码需要用到CMake或者直接使用命令行。引用[2]中提到了使用g++编译的命令,包括必要的编译选项和pybind11的包含路径。用户可能更倾向于使用CMake,因为引用[3]提到了CMAKE编译。因此,我需要提供一个简单的CMakeLists.txt示例,指导用户如何配置编译过程。 然后,测试部分也很重要。用户需要知道如何在Python中导入编译后的模块,创建类的实例,并调用其方法。这部分需要确保路径正确,并且示例代码能够直接运行。 此外,注意事项部分应该包括内存管理的问题,比如C++Python之间的对象所有权,以及异常处理。可能还需要提到如何传递不同类型的参数,比如const char*转换为std::string,这在引用[3]中也有涉及。 最后,根据用户的要求生成相关问题。这些问题应该围绕pybind11的高级用法、常见问题、性能优化等展开,帮助用户进一步学习。 需要确保步骤清晰,代码示例正确,并且符合用户提供的引用内容。特别是要引用正确的来源,比如在提到构造函数参数类型时引用[3],或者在编译命令时引用[2]。同时,所有代码块要正确格式化,数学公式如果有的话需要用正确的LaTeX格式,但本例中可能不需要数学公式。 总结步骤: 1. 创建C++类(头文件和实现) 2. 编写pybind11绑定代码 3. 配置CMakeLists.txt 4. 编译并生成Python模块 5. Python测试代码 6. 注意事项和相关问题 需要检查是否有遗漏的步骤,比如异常处理或参数转换的具体例子。另外,确保所有代码片段正确无误,特别是编译命令中的反引号是否正确转义,或者是否需要用更清晰的写法。</think>### 使用 pybind11 实现 Python 调用 C++ 类示例 以下是详细步骤和示例代码,展示如何通过 pybind11C++ 类暴露给 Python 使用: --- #### **1. 编写 C++ 类** 假设我们定义一个简单的 `DataProcessor` 类,包含构造函数、成员函数和属性: ```cpp // DataProcessor.h #include <string> class DataProcessor { public: DataProcessor(const std::string& file_path); // 构造函数 void mkdir_savefold(); // 创建文件夹 int process_data(int param); // 处理数据 std::string get_file_path() const; // 获取文件路径 private: std::string file_path_; }; ``` ```cpp // DataProcessor.cpp #include "DataProcessor.h" #include <iostream> #include <filesystem> DataProcessor::DataProcessor(const std::string& file_path) : file_path_(file_path) {} void DataProcessor::mkdir_savefold() { std::filesystem::create_directory(file_path_); std::cout << "文件夹已创建: " << file_path_ << std::endl; } int DataProcessor::process_data(int param) { return param * 2; } std::string DataProcessor::get_file_path() const { return file_path_; } ``` --- #### **2. 编写 pybind11 绑定代码** 创建 `bind.cpp` 文件,将 C++ 类绑定到 Python 模块: ```cpp #include <pybind11/pybind11.h> #include "DataProcessor.h" namespace py = pybind11; PYBIND11_MODULE(data_processor, m) { m.doc() = "Pybind11 示例:暴露 C++ 类给 Python"; // 绑定 DataProcessor 类 py::class_<DataProcessor>(m, "DataProcessor") .def(py::init<const std::string&>()) // 绑定构造函数 .def("mkdir_savefold", &DataProcessor::mkdir_savefold) .def("process_data", &DataProcessor::process_data) .def("get_file_path", &DataProcessor::get_file_path) .def_readwrite("file_path", &DataProcessor::file_path_); // 暴露成员变量(可选) } ``` --- #### **3. 配置 CMake 编译** 创建 `CMakeLists.txt` 文件,配置编译选项: ```cmake cmake_minimum_required(VERSION 3.12) project(data_processor) # 查找 pybind11 find_package(pybind11 REQUIRED) # 生成 Python 模块 add_subdirectory(pybind11) # 包含 pybind11 目录(假设已安装) pybind11_add_module(data_processor bind.cpp DataProcessor.cpp) ``` 编译命令: ```bash mkdir build && cd build cmake .. make ``` 成功后生成 `data_processor.cpython-xxx.so` 文件[^3]。 --- #### **4. Python 调用示例** 在 Python 中导入模块并使用 C++ 类: ```python import data_processor # 创建对象 processor = data_processor.DataProcessor("./output") # 调用方法 processor.mkdir_savefold() # 输出:文件夹已创建: ./output result = processor.process_data(5) print(result) # 输出:10 # 访问属性(如果暴露) print(processor.file_path) # 输出:./output ``` --- #### **注意事项** 1. **参数类型转换** C++ 的 `std::string` 会自动转换为 Python 的 `str`,基本类型(如 `int`)也会自动映射[^3]。 2. **内存管理** C++ 对象在 Python 中由 `pybind11` 自动管理生命周期,无需手动释放。 3. **异常处理** 若 C++ 代码抛出异常,pybind11 会将其转换为 Python 异常(如 `std::exception` 转为 `RuntimeError`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值