《人生苦短,我用python·三》pybind11简单使用

简介: 《人生苦短,我用python·三》pybind11简单使用

Pybind11 是一个轻量级的 C++ 库,用于将你的 C++ 代码暴露给 Python 调用(反之也可,但主要还是前者)。Pybind11 借鉴了 Boost::Python 库的设计,但使用了更为简洁的实现方式,使用了大量 C++11 的新特性,更易于使用。

对于Pybind11和Ctype方式都可以使用Python访问C++代码,但区别在于使用 PyBind11,我们可以更轻松地共享许多数据类型,而使用 ctypes 是一种低级的 C 样式解决方案,共享许多数据类型需要相当多的低级解决方法。例如,虽然ctypes不支持复数等基本的东西,但PyBind11使Numpy与Eigen完全互操作,需要最少的代码。

使用pybind11需要注意的是开发者使用哪个版本编译的pybind11,调用者也必须使用这个版本的python才可以调用。

Pybind11使用:

1、先安装pybind11

pip install pybind11

2、克隆pybind11代码

git clone pybind11代码(https://github.com/pybind/pybind11

3、加入Python头文件

(1)VS2019创建动态库(我这里是写了一个C++动态库专门存放pybind11的接口),在附加包含目录加入pybind11和python头文件(注意:动态库的cpp文件不要删掉,不然编译无法生产lib文件)

(2)附加库目录:

(3)附加依赖项:

(4)属性-配置属性-高级-目标文件扩展名-改为.pyd

(5)加入如下代码(案例):

#include <pybind11/pybind11.h>
#include<Python.h>
namespace py = pybind11;
PYBIND11_MODULE(pybind, m){
  m.doc() = "pybind11的案例";
  m.def("func", [](){return "这是pybind11的一个方法";}); 
}

编译成功会生成.pyd和.lib文件,可以在python中调用pybind11的方法或者类。

注意:PYBIND11_MODULE后面的名字和文件名要相同

一些常见用法案例:

当前文件名为pybindTest.h

#pragma once
#include <pybind11/pybind11.h>
#include<Python.h>
namespace py = pybind11;
const char* add(int i, int j) 
{
  return "helloworld";
}
PYBIND11_MODULE(pybindTest, m){
  //可选,说明这个模块是做什么的
  m.doc() = "pybind11的案例";
  //7/def(“给python调用方法名”,&实际操作的函效, 函数功能说明” ).其中函数功能说明为可选
  m.def("add", &add, "A function which adds two numbers", py::arg("i") = 1, py::arg("j") = 2):
}

第二条也可以写成m.def(“add”, &add);

python调用:

>>> import sys

>>> sys.path.append(“D:/pybindTest/x64/Debug/”)

>>> import pybindtest

>>> print(pybindtest.add(1,2))

Helloworld

案例2:

py::class_是用来给C++ class 或者 struct-style 的数据结构创建binding的。

py:: init()用来给相应的初始化函数创建binding。

#pragma once
#include <iostream>
#include <vector>
#include <pybind11/pybind11. h>
#include <Python.h>
#include <pybind11/st1.h> /1 函数中用到了C++的STL库,所以要包含该头文件
namespace py = pybind11;
//向量求和,返回一个向量
std::vector<doub1e> sum(const std::vector<doub1e>& vec1, const std::vector<doub1e>& vec2){
  auto result = vec1;
  for(int i = 0:i < vec1.size(); i++){
    result[i] += vec2[i];
  }
  return result;
}
//定义一个向量类
c1ass Vector {
public:
  Vector() = default;
  ~Vector() = default;
  std::vector<double> sum(const std::vector<doub1e>& vecl, const std::vector<double>& vec2) {
    auto result = vec1;
    for(int i=0;i<vec1.size():i++){
      result[i] += vec2[i];
    }
    return result;
  }
}
PYBIND11_MODULE(pybindTest, m){
  //可选,说明这个模块是做什么的
  m.doc() = "pybind11的案例";
  //封装函数
  m.def(sum,&sum);
  //封装类
  pybindll::class_<Vector> (m "Vector")
    .def(pybind1::init())
    .def("sum", &Vector::sum);
}

pybind11封装QT动态库:

Intrument_Controll.h是QT动态库的一个头文件,想要调用这个头文件类中的方法那么需要创建QT动态库,C++动态库不可以调用QT动态库,用pybind11封装好后,在Python命令行下创建对象报错:

在目录下面明明有pybindtest2.pyd文件为啥调用不了?很可能是缺少某些DLL。现在在项目-属性-高级-目标文件扩展名把.pyd改回.dll,编译生成dll后用depend查看pybindtest2.dll缺少哪些dll,查看后得知缺少QT5CORED.DLL。

进入D:\QT\5.15.2\msvc2019_64\bin目录下把QT5CORED.DLL拷贝到pybindtest2目录下然后能正常调用。

注意:pybind11会自动析构间接的类指针

GetModuleByID(1)返回的是IMonocular指针多态调用Monocular子类方法,在GetCaptureDate之后在重复调用一次发现IMonocular指针已经被自动析构了,这种用指针间接调用方式想要不被自动析构有两个方法:

方法一:

写成直接方式:

ptr = intrument.GetModuleByID(1)

data = ptr.GetCaptureDate()

data = ptr.GetCaptureDate()

方式二:

在绑定的子类后面加std::unique_ptr<Monocular, py::nodelete>这样在间接调用类指针的时候不会被主动析构。

python类继承C++中的抽象类:

先在外层写一个中间类继承抽象类,中间类中成员方法的实现格式如下:

案例:MLCameraCallback是一个抽象类

然后在PYBIND11_MODULE(MLColorimeter_py, m)中如下实现:

在python中实现类继承C++抽象类MLCameraCallBack:

📢博客主页: 主页

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

📢本文由 梦回阑珊 原创,首发于 CSDN,转载注明出处🙉

📢代码改变世界,你来改变代码!✨

相关文章
|
机器学习/深度学习 人工智能 数据可视化
【好物分享】onnx-modifier:可视化操作助力模型更改,让你不再为更改模型烦恼!
【好物分享】onnx-modifier:可视化操作助力模型更改,让你不再为更改模型烦恼!
2212 0
【好物分享】onnx-modifier:可视化操作助力模型更改,让你不再为更改模型烦恼!
|
编解码 UED
Qt侧边栏的动态切换:隐藏与显示技术详解
在现代用户界面设计中,侧边栏(Sidebar)是一个常见的组件,它为用户提供了导航和工具面板的功能。在某些应用场景下,我们可能需要动态地隐藏或显示侧边栏,以优化界面布局或提供更灵活的用户体验。本文将分享如何在Qt框架下实现侧边栏的隐藏与呈现,包括技术细节和代码示例。
1132 3
|
PyTorch API 算法框架/工具
AscendC从入门到精通系列(四)使用Pybind调用AscendC算子
本文介绍了如何通过Pybind11在PyTorch框架中调用自定义的Ascend C算子。首先,通过编写算子的C++实现和pybind11封装,将算子功能暴露给Python。接着,构建Python调用脚本,利用torch接口生成数据并调用封装好的算子模块。最后,通过CMake配置文件编译整个项目,实现从算子开发到测试的完整流程。
|
C++ Python
【C++/Python】C++调用python文件
【C++/Python】C++调用python文件
|
Unix C语言 C++
Python调用C/C++
Python调用C/C++
637 2
QML 界面切换的方法
QML 界面切换的方法
840 1
|
测试技术 开发工具 git
面向 C++ 的现代 CMake 教程(三)(3)
面向 C++ 的现代 CMake 教程(三)
511 0
|
C++ Python
【Pybind11】pybind11在visual studio中的配置
【Pybind11】pybind11在visual studio中的配置
|
Java 测试技术 语音技术
开源上新|FunASR英文离线文件转写软件包发布
开源上新|FunASR英文离线文件转写软件包发布