热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

混合编程:如何用pybind11调用C++

摘要:在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对性能要求高的情景下面,还是需要使用cc++来完成。本文分享自华为云社区《混

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


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 list_square(vector &in_list, vector& out_list){
vector::iterator iter;
for(iter = in_list.begin(); iter != in_list.end(); iter++){
out_list.push_back(*iter * *iter);
}
return out_list;
}

map dict_square(map& in_dict, map& out_dict){
map::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


#include


#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


#include
struct Foo {
std::string a;
};
void show(Foo f) {
std::cout <}
namespace py = pybind11;
PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin");
m.def("show", &show, "Prints a");
py::class_(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)

 

点击关注,第一时间了解华为云新鲜技术~



推荐阅读
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 树莓派Linux基础(一):查看文件系统的命令行操作
    本文介绍了在树莓派上通过SSH服务使用命令行查看文件系统的操作,包括cd命令用于变更目录、pwd命令用于显示当前目录位置、ls命令用于显示文件和目录列表。详细讲解了这些命令的使用方法和注意事项。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • importjava.util.ArrayList;publicclassPageIndex{privateintpageSize;每页要显示的行privateintpageNum ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
author-avatar
情人節快樂1991的名单
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有