混合编程:如何用pybind11调用C++
摘要:在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对性能要求高的情景下面,还是需要使用c/c++来完成。
本文分享自华为云社区《混合编程:如何用pybind11调用C++》,作者:SNHer。
在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对性能要求高的情景下面,还是需要使用c/c++来完成。那怎样做呢?我们能使用pybind11作为桥梁,pybind11的优点是对C++ 11支持很好,API比较简单,现在我们就简单记下Pybind11的入门操作。
1.pybind11简介与环境安装
Pybind11 是一个轻量级只包含头文件的库,用于 Python 和 C++ 之间接口转换,可以为现有的 C++ 代码创建 Python 接口绑定。Pybind11 通过 C++ 编译时的自省来推断类型信息,来最大程度地减少传统拓展 Python 模块时繁杂的样板代码, 已经实现了 STL 数据结构、智能指针、类、函数重载、实例方法等到Python的转换,其中函数可以接收和返回自定义数据类型的值、指针或引用。
直接使用pip安装 pip3 install pybind11 由于pybind11依赖于pytest,所以在安装前需要先把pytest给安装上 pip3 install pytest
2. 求和函数
首先,我们编写一个C++源文件,命名为example.cpp。
// pybind11 头文件和命名空间
#include <pybind11/pybind11.h>
namespace py = pybind11; int add(int i, int j)
{
return i + j;
} PYBIND11_MODULE(example, m)
{
// 可选,说明这个模块是做什么的
m.doc() = "pybind11 example plugin";
//def( "给python调用方法名", &实际操作的函数, "函数功能说明" ). 其中函数功能说明为可选
m.def("add", &add, "A function which adds two numbers", py::arg("i")=1, py::arg("j")=2);
}
PYBIND11_MODULE()宏函数将会创建一个函数,在由Python发起import语句时该函数将会被调用。模块名字“example”,由宏的第一个参数指定(千万不能出现引号)。第二个参数"m",定义了一个py::module的变量。函数py::module::def()生成绑定代码,将add()函数暴露给Python。
我们使用CMake进行编译。首先写一个CMakeLists.txt。
cmake_minimum_required(VERSION 2.8.12)
project(example) add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)
就是CMakeList.txt和example.cpp放在一个目录下面。
cmake .
make
会生成example.cpython-36m-x86_64-linux-gnu.so文件。
这个文件就是python可以调用的文件。还是在相同目录下运行python,进入python命令行
import example
example.add(3, 4)
[out]: 7
3. STL和python内建数据类型的对应关系
在使用python编程时,常使用内建容器作为函数的参数和返回值,python语言的这种特性使我们的程序变得非常灵活和易于理解。那么在使用pybind11封装C++实现的函数的时候,如何保留这一特性呢?本文介绍pybind11实现list和dict作为参数及返回值的方法。

返回vector
//文件名:func.cpp
#include "func.h" vector<long> list_square(vector<long> &in_list, vector<long>& out_list){
vector<long>::iterator iter;
for(iter = in_list.begin(); iter != in_list.end(); iter++){
out_list.push_back(*iter * *iter);
}
return out_list;
} map<string, long> dict_square(map<string, long>& in_dict, map<string, long>& out_dict){
map<string, long>::iterator iter;
iter = in_dict.begin();
while(iter != in_dict.end()){
out_dict.insert({iter->first, iter->second * iter->second});
iter++;
}
return out_dict;
}
- 写pybind11封装函数
//文件名:func_wrapper.cpp
#include <pybind11/pybind11.h>
#include<pybind11/stl.h>
#include "func.h" PYBIND11_MODULE(square, m){
m.doc() = "Square the members of the container";
m.def("list_square", &list_square);
m.def("dict_square", &dict_square);
}
返回struct
#include <pybind11/pybind11.h>
#include <iostream>
struct Foo {
std::string a;
}; void show(Foo f) {
std::cout << f.a << std::endl;
} namespace py = pybind11; PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin"); m.def("show", &show, "Prints a");
py::class_<Foo>(m, "Foo")
.def_readwrite("a", &Foo::a); return m.ptr();
}
- 写pybind11封装函数
import sys
sys.path.append(".")
import example b = example.Foo
b.a = "Hello"
example.show(b)
混合编程:如何用pybind11调用C++的更多相关文章
- Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)
原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了mat ...
- 【混合编程】C/C++调用Fortran的DLL
[混合编程]C/C++调用Fortran的DLL 以一个简单的加法器为例,介绍C/C++调用Fortran语言DLL的操作过程 一.Fortran操作 1.1 Fortran代码 首先是加法功能的实现 ...
- 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...
- 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...
- 【目录】Matlab和C#混合编程文章目录
本博客所有文章分类的总目录链接:[总目录]本博客博文总目录-实时更新 1.Matlab和C#混合编程文章目录 9.接触Matlab10年后的一个总结,随时使用Matlab要掌握的一些要点 8.国内第一 ...
- FFT原理及C++与MATLAB混合编程详细介绍
一:FFT原理 1.1 DFT计算 在一个周期内的离散傅里叶级数(DFS)变换定义为离散傅里叶变换(DFT). \[\begin{cases} X(k) = \sum_{n=0}^{N-1}x(n)W ...
- 混合编程:如何用python11调用C++
摘要:在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对性能要求高的情景下面,还是需要使用c/c++来完成. 那怎样做呢?我们能使用pybind11作 ...
- matlab和C/C++混合编程--调用opencv
最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...
- [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库
前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...
- 【环境】VS2013和MATLAB相互调用混合编程
Visual Studio和MATLAB混合编程,有两种方法: 1 MATLAB调用C程序: 2 VS调用MATLAB(目前见到的都是VS,其他编译器如codeblocks,或不提供这项功能): 前一 ...
随机推荐
- 动态规划的状态设计 | bot 讲课の补题
sto james1badcreeper orz. 好厉害的题,但是怎么有人补了三天才补完呢? CF1810G The Maximum Prefix 线性 dp,怎么有 bot 说题目难度在 *240 ...
- JVM-JAVA基本类型
1 package javap.fload; 2 3 import static jdk.nashorn.internal.objects.Global.Infinity; 4 5 public cl ...
- C/C++ 开发SCM服务管理组件
SCM(Service Control Manager)服务管理器是 Windows 操作系统中的一个关键组件,负责管理系统服务的启动.停止和配置.服务是一种在后台运行的应用程序,可以在系统启动时自动 ...
- Jenkins从Ubuntu迁移至AlmaLinux问题及相关解决记录
相关背景 之前在Ubuntu平台上搭建了Jenkins(在Ubuntu机器上使用war包安装Jenkins),现在由于一些需求,需要将系统迁移到AlmaLinux平台.由于AlmaLinux属于Cen ...
- 2019-2020 ICPC Southwestern European Regional Programming Contest (SWERC 2019-20) L题(SG+状压)
题意:给定一个N*N的表格,其上有三种类型的方格:坚实的地面.潮湿的区域和保护区.连通的湿区方格形成湿区,当两个正方形共用一条边时,它们被认为是连接的.每个湿区必须连接到网格的左右两侧,并且不包含超过 ...
- 黑客玩具入门——5、继续Metasploit
1.利用FTP漏洞并植入后门 实验靶机:Metasploitable2. 实践: 使用nmap扫描目标靶机 nmap -sV xxx.xxx.xxx.xxx(目标ip) 生成linux系统后门 msf ...
- 你真的了解HashSet 和HashMap的区别、优缺点、使用场景吗?
HashSet 和 HashMap 是 Java 集合框架中的两个常用类,它们都用于存储和管理数据,但在使用方式.功能和性能上有很大的区别. HashSet 和 HashMap 的区别 区别一:用途不 ...
- Vue-cli脚手架下载安装
注意:在下载安装该脚手架之前先安装配置好NodeJS以及镜像源,NodeJS详情可查询文章:NodeJS下载安装 1.cmd中输入以下指令: npm install -g @vue/cli 整个过程中 ...
- 怎么在Android项目中导入ffmpeg库?
1.前言 在这里我以导入静态库(.a)为例进行分析,动态库(.so)是类似的.在导入前,各位要先编译好ffmpeg库,需要注意的是在编译的时候要开启交叉编译,目标平台为Android,其他平台的库(w ...
- 【Buildroot】工具包使用
一.测试环境 开发板:rv1126 buildroot版本:2018.02-rc3 二..mk规则 PKG_NAME:定义软件包的名称.通常与软件包源代码的目录名相同. PKG_VERSION:定义软 ...