1.封装cpp给python调用,提高程序开发和运行效率

将cpp代码编译成python可以调用的模块,充分利用两种语言的优缺点互补,提高程序开发和运行效率

目录

1
2
3
4
5
6
7
project/
├── build/
│ ├── example.pyd
│ └── ...
├── example.cpp
├── main.py
└── CMakeLists.txt

环境安装

1
pip install pybind11

代码准备

example.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <pybind11/pybind11.h>

class MyClass
{
public:
MyClass(int val) : value(val) {}

int get_value() const
{
return value;
}

void set_value(int val)
{
value = val;
}

int add(int a) const
{
return value + a;
}

private:
int value;
};

PYBIND11_MODULE(example, m)
{
pybind11::class_<MyClass>(m, "MyClass")
.def(pybind11::init<int>()) // 构造函数
.def("get_value", &MyClass::get_value) // 获取值的方法
.def("set_value", &MyClass::set_value) // 设置值的方法
.def("add", &MyClass::add); // add 方法
}

cmake编译

CMakeLists.txt

mkdir build
cd build
cmake .. -G "MinGW Makefiles"
make
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cmake_minimum_required(VERSION 3.12)
project(example)

set(CMAKE_CXX_STANDARD 14)

# Find pybind11
set(CMAKE_PREFIX_PATH "d:/English/anaconda3/Lib/site-packages/pybind11/share/cmake/pybind11" ${CMAKE_PREFIX_PATH})
find_package(pybind11 REQUIRED)

# 创建共享库(.pyd)
add_library(example MODULE example.cpp)

# 设置输出文件扩展名为 .pyd
set_target_properties(example PROPERTIES
PREFIX ""
SUFFIX ".pyd"
)
# 链接 pybind11 库
target_link_libraries(example PRIVATE pybind11::module)

python调用

1
2
3
4
5
6
7
8
9
10
import build.example as example
#创建 MyClass 对象
obj = example.MyClass(10)
# 调用方法
print(obj.get_value()) # 输出 10
obj.set_value(20)
print(obj.get_value()) # 输出 20

result = obj.add(5) # 20 + 5 = 25
print(result) # 输出 25

应用

第五届EDA精英挑战赛赛题八-标准单元电路的版图自动生成,将模拟退火的关键部分使用c++实现,并封装成python模块,再结合python标准库实现晶体版图自动布局,效率提高为纯c++的两倍和纯python的数倍。
SApython接口
SA核心动态库