pybind11:实现Python调用C++代码(入门)

pybind11简介

pybind11 是一个开源的 C++ 和 Python 之间的桥接工具,它旨在使 C++ 代码能够无缝地集成到 Python 环境中。pybind11 的设计目标是简化 C++ 与 Python 的互操作性,使开发者能够更轻松地将现有的 C++ 库/代码包装为可以在 Python 中使用的模块。

pybind11 是一个非常受欢迎和有用的 Python 软件包,尤其在将现有的 C++ 代码集成到 Python 环境中时非常有用。它得到了广泛的应用,在科学计算、机器学习、计算机图形学等领域都有很多使用案例。

pybind11安装和配置(Windows)

pybind11是个C++的header-only的库。因此无需安装,只需要有头文件即可。

这是pybind11的github:https://github.com/pybind/pybind11, 可以直到github下安装,或者用git克隆:

git clone https://github.com/pybind/pybind11 --depth=1

若输入上面指令出现 “SSL certificate problem: unable to get local issuer certificate” 缺少根证书的问题则使用指令:

git -c http.sslVerify=false clone https://github.com/pybind/pybind11 --depth=1

使得Git 克隆仓库时禁用 SSL 证书验证(该操作具有一定风险,确保仓库可信)

克隆后得到一个名为 “pybind11” 的文件夹,创建一个C++项目,在项目内将pybind作为一个外部库。用cmake管理,注意,官方文档中写到了 “On Windows, only Visual Studio 2017 and newer are supported.” 意思就是只有Vistual Studio 2017 或更高版本支持配置这个库

guanfan

只能采用Vistual Studio的编译工具包括cmake,为了操作方便,我们在vscode中打开这个项目(vscode可以使用Vistual Studio的工具)

vscodewj

准备4个文件,一个是外部库Pybind11,一个是CMakeLists.txt文件,一个cpp文件,一个python文件。(先准备cmakelists文件和选择编译工具包)

CMakeLists.txt

# 版本号无关轻重
cmake_minimum_required(VERSION 3.23)

# 项目名称
project(tryPybind)

# 指定python解释器的位置
set(PYTHON EXECUTABLE "C:/Users/27966/AppData/Local/Programs/Python/Python311/python.exe")

# 添加pybind11到项目
add_subdirectory(extern/pybind11)

# pybind11的一个cmake函数 将tryPybind.cpp编译成一个C++模块,并绑定python,生成一个python可导入的拓展模块,"tryPybind"即为模块名
Pybind11_add_module(tryPybind tryPybind.cpp)

用vscode打开你准备好的项目后会提示你选择工具包

gj

选择visual studio的第一个工具包

build

等待配置好后项目后直接点击生成即可(CMakeLists.txt文件和cpp文件(稍后介绍)没问题则能正确生成),在当前目录下就会自动生成一个build文件夹,文件夹里有个Debug文件夹 (也可能是Release 一样的用法),这里面生成了4个文件,其中:

.pyd是python的动态库

.exp是windows下面的导出库文件,它包含了导出函数和数据项的信息

.lib是windows下面的c++静态库

.pdb是Windows调试符号文件(若是release则没有这个文件)

four

这里面的pyd文件便能实现python代码中调用C++的代码的功能,下面是cpp文件的创建以绑定一个函数或类。

绑定一个C++函数

#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;

//绑定一个函数
int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(tryPybind, m) {
    m.def("add", &add);
}

这段的意思就是:

利用PYBIND11_MODULE这个宏,它接受两个参数。第一个tryPybind是模块名,第二个参数不用管,就m就行
m.def就是定义一个python中的函数,函数名为add,函数绑定到c++的add函数。

运行cmake生成build后,生成的pyd文件拖放到当前目录下(确保和py文件一个目录下),编写python脚本:

pyTry.py

import tryPybind

a = tryPybind.add(1, 2)

print(a)

输出:

3

这样就成功在python代码中调用了一个C++函数

绑定一个c++的类

直接把c++的源码改为:

tryPybind.cpp

#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;

//绑定一个类
class SomeClass
{
    float scale;
public:
    SomeClass(float scale_) : scale(scale_) { };
    float multiply(float input) {
        float res =  scale * input;
        std::cout<<"res:"<<res<<std::endl;
        return res;
    }
};

PYBIND11_MODULE(tryPybind,m)
{
    py::class_<SomeClass>(m, "SomeClass")
        .def("multiply", &SomeClass::multiply)
        .def(py::init<float>());
}

这段的意思和上面大体相同,多出来的部分就是:

class_定义一下类名“SomeClass”
.def定义类函数(构造函数要单独用python的init定义)

同样的操作,cmake后得到一个pyd文件,拖放到当前目录,定义python脚本:

pyTry.py

import tryPybind

print(dir(tryPybind))
a = tryPybind.SomeClass(2.1)
a.multiply(2.0)

输出:

['SomeClass', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
res:4.2

这样就成功在python代码中调用了一个C++类

以下是一些具体是应用:

pybind11:实现ndarray转C++原生数组

pybind11:对比C++和Python解线性方程组的速度

  • 32
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值