摘要:在实际开发过程中,免不了涉及到混合编程,比如,对于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++的更多相关文章

  1. Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)

    原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了mat ...

  2. 【混合编程】C/C++调用Fortran的DLL

    [混合编程]C/C++调用Fortran的DLL 以一个简单的加法器为例,介绍C/C++调用Fortran语言DLL的操作过程 一.Fortran操作 1.1 Fortran代码 首先是加法功能的实现 ...

  3. 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...

  4. 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...

  5. 【目录】Matlab和C#混合编程文章目录

    本博客所有文章分类的总目录链接:[总目录]本博客博文总目录-实时更新 1.Matlab和C#混合编程文章目录 9.接触Matlab10年后的一个总结,随时使用Matlab要掌握的一些要点 8.国内第一 ...

  6. FFT原理及C++与MATLAB混合编程详细介绍

    一:FFT原理 1.1 DFT计算 在一个周期内的离散傅里叶级数(DFS)变换定义为离散傅里叶变换(DFT). \[\begin{cases} X(k) = \sum_{n=0}^{N-1}x(n)W ...

  7. 混合编程:如何用python11调用C++

    摘要:在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对性能要求高的情景下面,还是需要使用c/c++来完成. 那怎样做呢?我们能使用pybind11作 ...

  8. matlab和C/C++混合编程--调用opencv

    最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...

  9. [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库

    前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...

  10. 【环境】VS2013和MATLAB相互调用混合编程

    Visual Studio和MATLAB混合编程,有两种方法: 1 MATLAB调用C程序: 2 VS调用MATLAB(目前见到的都是VS,其他编译器如codeblocks,或不提供这项功能): 前一 ...

随机推荐

  1. 实战|如何低成本训练一个可以超越 70B Llama2 的模型 Zephyr-7B

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  2. k8s Redis安装部署

    一.文档简介 作者:lanjiaxuan 邮箱:lanheader@163.com 博客地址:https://www.cnblogs.com/lanheader/ 更新时间:2021-07-09 安装 ...

  3. java4.switch条件语句、循环结构

    switch条件语句.循环结构 循环结构 while 1.先判断再执行代码 2.代码块至少执行0次 do-while- 1.先执行代码再执行判断 2.代码块至少执行1次 for 1.用于编写已知循环次 ...

  4. [C++]P5024 树形DP 保卫王国

    树形DP 保卫王国P5024 前置知识 1.邻接表 + Dfs(深度优先搜索) 2.基础DP(如 01背包 ) 3.最小公共祖先(LCA) LCA我有写过Blog 首先解读一下题意 城市即为节点 每个 ...

  5. SpringBoot+Redis实现接口级别缓存信息

    本文主要讲述如何通过SpringBoot+Redis实现接口级别缓存信息 背景 近期因为一直在处理公司的老项目,恰好碰到产品说页面有一些信息展示慢,简单看了一下页面接口,发现查询的是系统中几张大表(数 ...

  6. [Python急救站课程]获取星期字符串

    如何获取星期字符串 weekstr = "星期一星期二星期三星期四星期五星期六星期日" weekid = eval(input("请输入星期数字(1~7):") ...

  7. FHQ_Treap学习笔记

    前置芝士(了解即可啦~):C++.BST 二叉搜索树.堆.二叉堆 Treap 的概念 Treap 树堆,即树(Tree)+堆(Heap),是一棵弱平衡的二叉搜索树(BST),能同时满足二叉搜索树与堆的 ...

  8. 火山引擎 DataLeap 计算治理自动化解决方案实践和思考

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 [导读]本文旨在探讨火山引擎 DataLeap 在处理计算治理过程中所面临的问题及其解决方案,并展示这些解决方案带 ...

  9. 洛谷P2579 [ZJOI2005]沼泽鳄鱼(矩阵快速幂,周期)

    例题:现在豆豆已经选好了两座石墩Start和End,他想从Start出发,经过K个单位时间后恰好站在石墩End上.假设石墩可以重复经过(包括Start和End),他想请你帮忙算算,这样的路线共有多少种 ...

  10. 0x03.api接口

    API接口安全 HTTP类接口 SOAP----->http+xml REST------>传递资源 RPC类接口(非web):用于远程调用,类似于客户端和服务端.如,登录的时候,进入服务 ...