背景
爱写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很高兴,终于感觉自己所学的东西并不会很割裂,也许以后能够组合起来进行运用。
本文章上有什么问题都可以和博主联系。