Python调用C++,通过Pybind11制作Python接口


Posted in Python onOctober 16, 2018

我是在ubuntu系统进行实验的,所以和window可能会有区别。

python调用C/C++有不少的方法,如boost.python, swig, ctypes, pybind11等,这些方法有繁有简,而pybind11的优点是对C++ 11支持很好,API比较简单,现在我们就简单记下Pybind11的入门操作。

1. pybind11简介与环境安装

pybind11是一个轻量级的只包含头文件的库,它主要是用来在已有的 C++代码的基础上做扩展,它的语法和目标非常像Boost.Python,但Boost.Python为了兼容现有的基本所有的C++编译器而变得非常复杂和庞大,而因此付出的代价是很多晦涩的模板技巧以及很多不必要的对旧版编译器的支持。Pybind11摒弃了这些支持,它只支持python2.7以上以及C++ 11以上的编译器,使得它比Boost.Python更加简洁高效。

为了使用pybind11,我们需要支持C++ 11标准的编译器(GCC 4.8以上,VS 2015 Update 3以上)以及python 2.7以上的版本,还需要下载CMake,有了这些以后,

cmake教程可以参考://3water.com/article/148903.htm

  1. 首先,我们从 pybind11 github网址:https://github.com/pybind/pybind11 上下载源码。
  2. cmake工程之前,要先安装pytest pip install pytest,否则会出错
  3. 用CMake编译并运行测试用例:
进入pybind11的目录,
cd tests
cmake ..
cmake --build . --config Release --target check

如果所有测试用例都通过了,说明安装成功了。

2. python调用C++

下载编译好pybind11之后,我们就可以开始对着官方的pybind11 Tutorial进行学习了,详细的入门教程及语法请参考官方文档,这里,我们简单演示下如何编写供python调用的C++模块.
首先,我们编写一个C++源文件,命名为example.cpp

#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j)
{
 return i + j;
}
PYBIND11_MODULE(example, m)
{
 // optional module docstring
 m.doc() = "pybind11 example plugin";
 // expose add function, and add keyword arguments and default arguments
 m.def("add", &add, "A function which adds two numbers", py::arg("i")=1, py::arg("j")=2);
 // exporting variables
 m.attr("the_answer") = 42;
 py::object world = py::cast("World");
 m.attr("what") = world;
}

2.1 使用window编译

我没有实验,所以可以参考别的教程

2.2 CMake的编译方法

当然,我们也可以使用CMake进行编译。首先写一个CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)
project(example) 
add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

这里要求example.cpp放在和pybind11同一级的目录下,因为我们在CMakeLists.txt中调用了同目录pybind11和同目录的example.cpp文件。在当前目录下执行

cmake .
make

会生成example.cpython-36m-x86_64-linux-gnu.so文件。这个文件就是python可以调用的文件。还是在相同目录下运行python,进入python命令行

import example
example.add(3, 4)
[out]: 7

3、中级调用

上面是一个简单的例子,有时我们需要的功能可能很复杂。

生成模型设计库调用问题。

比如你的cpp文件中引用了其他的第三方库,这个时候我们生成的so文件,可能是需要依赖第三方库的。

本地myopencv.cpp文件

#include <pybind11/pybind11.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <string>
namespace py = pybind11;
void read_img(std::string img_path)
{
 cv::Mat image = cv::imread(img_path, CV_LOAD_IMAGE_COLOR);
}
PYBIND11_MODULE(myopencv, m)
{
 m.def("read_img", &read_img, "get image size");
}

CMakeLists.txt可以写成下面这样

cmake_minimum_required(VERSION 2.8.12)
project(myopencv)
add_subdirectory(pybind11)
pybind11_add_module(myopencv myopencv.cpp)

通过cmkae编译通过

cmake .
make

产生myopencv.cpython-36m-x86_64-linux-gnu.so文件
在python中调用

import myopencv

目前这里发现有问题,还没有调通

数据类型不匹配的问题

比如opencv在python中是numpy的类型,但是在c++中cv.Mat的类型

对于opencv的类型不匹配问题,github上已经给出了解决方法,

cpp和h文件下载地址 https://github.com/edmBernard/pybind11_opencv_numpy

如何你需要什么可以去github上搜索,或者自己去实现。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

Python 相关文章推荐
python正则匹配查询港澳通行证办理进度示例分享
Dec 27 Python
在服务器端实现无间断部署Python应用的教程
Apr 16 Python
python登录豆瓣并发帖的方法
Jul 08 Python
使用Python判断质数(素数)的简单方法讲解
May 05 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
Feb 14 Python
Python对列表中的各项进行关联详解
Aug 15 Python
浅谈python连续赋值可能引发的错误
Nov 10 Python
Python内存管理实例分析
Jul 10 Python
详解Python可视化神器Yellowbrick使用
Nov 11 Python
浅谈pycharm导入pandas包遇到的问题及解决
Jun 01 Python
Python图像处理二值化方法实例汇总
Jul 24 Python
python munch库的使用解析
May 25 Python
Python之inspect模块实现获取加载模块路径的方法
Oct 16 #Python
django 将model转换为字典的方法示例
Oct 16 #Python
python复制列表时[:]和[::]之间有什么区别
Oct 16 #Python
使用Python编写Prometheus监控的方法
Oct 15 #Python
python取数作为临时极大值(极小值)的方法
Oct 15 #Python
Python文件监听工具pyinotify与watchdog实例
Oct 15 #Python
Python并行分布式框架Celery详解
Oct 15 #Python
You might like
php基础知识:类与对象(3) 构造函数和析构函数
2006/12/13 PHP
ajax+php打造进度条代码[readyState各状态说明]
2010/04/12 PHP
《PHP编程最快明白》第七讲:php图片验证码与缩略图
2010/11/01 PHP
Zend Framework框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法
2016/03/21 PHP
Javascript MD4
2006/12/20 Javascript
escape、encodeURI 和 encodeURIComponent 的区别
2009/03/02 Javascript
js 小贴士一星期合集
2010/04/07 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
2013/01/23 Javascript
通过length属性判断jquery对象是否存在
2013/10/18 Javascript
JavaScript定时显示广告代码分享
2015/03/02 Javascript
jquery中toggle函数交替使用问题
2015/06/22 Javascript
jquery validate demo 基础
2015/10/29 Javascript
JS模拟的Map类实现方法
2016/06/17 Javascript
JavaScript中的this使用详解
2016/07/27 Javascript
微信小程序 生命周期详解
2016/10/12 Javascript
详解js产生对象的3种基本方式(工厂模式,构造函数模式,原型模式)
2017/01/09 Javascript
AngularJS的ng-repeat指令与scope继承关系实例详解
2017/01/21 Javascript
jQuery.cookie.js使用方法及相关参数解释
2017/03/06 Javascript
利用Vue.js+Node.js+MongoDB实现一个博客系统(附源码)
2017/04/24 Javascript
JavaScript简单实现关键字文本搜索高亮显示功能示例
2018/07/25 Javascript
微信小程序封装自定义弹窗的实现代码
2019/05/08 Javascript
微信小程序文章详情页跳转案例详解
2019/07/09 Javascript
JS根据Unix时间戳显示发布时间是多久前【项目实测】
2019/07/10 Javascript
Javascript call及apply应用场景及实例
2020/08/26 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:奇迹哥卡尔秀翻全场
2017/03/28 DOTA
python调用shell的方法
2013/11/20 Python
基于pandas中expand的作用详解
2019/12/17 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
美国购买当代和现代家具网站:MODTEMPO
2018/07/20 全球购物
电子信息科学专业自荐信
2014/01/30 职场文书
学校课外活动总结
2014/05/08 职场文书
优秀小学生事迹材料
2014/12/26 职场文书
培训班开班主持词
2015/07/02 职场文书
2016元旦晚会主持词开场白和结束语
2015/12/04 职场文书
2019年销售人员的职业生涯规划书
2019/03/25 职场文书
PostgreSQL通过oracle_fdw访问Oracle数据的实现步骤
2021/05/21 PostgreSQL