0. 前言:
工业界经常使用 pybind 11 封装 C++ 成 python 代码,这样既有 C++ 的性能,也有 python 胶水语言的方便;因此,本文使用 pybind 11 封装 C++ 的 map, vector 来说明这样的例子;
1. 封装 C++ 代码的 map<int, int>例子
- 下面是一个简单的示例,展示如何使用 pybind11 封装一个 C++ 的 map<int, int> 类型的代码:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <map>
namespace py = pybind11;
// 定义一个函数,用于接收 Python 传递过来的 map<int, int> 对象
void process_map(const std::map<int, int>& my_map) {
// 遍历 map,并输出每个键值对
for (const auto& pair : my_map) {
py::print(pair.first, pair.second);
}
}
// 创建一个 Python 模块
PYBIND11_MODULE(map_example, m) {
m.def("process_map", &process_map, "Process a map<int, int> object");
}
- C++ 代码封装为 Python 模块:
import map_example
# 创建一个新的 map 对象并传递给 C++ 函数进行处理
my_map = {1: 10, 2: 20, 3: 30}
map_example.process_map(my_map)
- 运行此 Python 脚本将输出以下内容:
1 10
2 20
3 30
这样就成功地封装了一个 C++ 的 map<int, int> 类型,并在 Python 中使用了它。
2. 封装 std::vector 函数的例子
- 下面是一个使用 pybind11 封装 std::vector 输入的示例代码,其中 ClassExample 是定义的类
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <vector>
namespace py = pybind11;
// 定义一个类
class ClassExample {
public:
int value;
ClassExample(int val) : value(val) {}
void print() {
py::print("Value:", value);
}
};
// 定义一个函数,用于接收 Python 传递过来的 std::vector<ClassExample> 对象
void process_vector(const std::vector<ClassExample>& my_vector) {
// 遍历 vector,并调用每个对象的 print() 方法
for (const auto& item : my_vector) {
item.print();
}
}
// 创建一个 Python 模块
PYBIND11_MODULE(vector_example, m) {
// 定义 ClassExample 类
py::class_<ClassExample>(m, "ClassExample")
.def(py::init<int>())
.def("print", &ClassExample::print);
// 将 process_vector 函数封装为一个 Python 可调用对象
m.def("process_vector", [](const std::vector<ClassExample>& my_vector) {
for (const auto& item : my_vector) {
item.print();
}
}, "Process a vector of ClassExample objects");
}
- C++ 代码封装为 Python 模块:
import vector_example
# 创建一个新的 vector,并传递给 C++ 函数进行处理
my_vector = [vector_example.ClassExample(1), vector_example.ClassExample(2), vector_example.ClassExample(3)]
vector_example.process_vector(my_vector)
- 运行 Python 脚本将输出以下内容:
Value: 1
Value: 2
Value: 3
这样就成功地封装了一个 C++ 的 std::vector 类型,并在 Python 中使用了它。
3. pybind11 的 CMakeLists.txt 的示例
下面是一个示例的 CMakeLists.txt 文件,用于构建上述的 pybind11 封装代码:
cmake_minimum_required(VERSION 3.12)
project(my_module)
# 设置编译选项
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找 pybind11
find_package(pybind11 REQUIRED)
# 添加模块目标
pybind11_add_module(vector_example MODULE vector_example.cpp)
# 链接所需的库和头文件
target_link_libraries(vector_example PRIVATE pybind11::module)
# 安装目标库
install(TARGETS vector_example LIBRARY DESTINATION .)
将上述 CMakeLists.txt 文件放置在与源代码文件相同的目录中,并使用以下命令构建和安装模块:
mkdir build
cd build
cmake ..
make
sudo make install # 如果需要系统级安装,否则可省略 sudo 命令
然后,可以在 Python 中导入 vector_example 模块并使用封装后的函数。