当前位置: 首页 > 编程日记 > 正文

pybind11介绍

      pybind11是一个轻量级的仅头文件库,主要用于创建现有C++代码的Python绑定,它的源码在https://github.com/pybind/pybind11,license为BSD,最新发布版本为2.9.1。

      可将pybind11库视为Boost.Python的一个小型自包含版本(Think of this library as a tiny self-contained version of Boost.Python),其中剥离了与绑定生成无关的所有内容。pybind11依赖于python(2.7或3.5+)和C++标准库

      pybind11核心功能:pybind11可以将以下C++功能映射到Python

      (1).函数接受和返回自定义数据结构(per value, reference, or pointer);

      (2).实例方法和静态方法;

      (3).重载函数;

      (4).实例属性和静态属性;

      (5).任意异常类型;

      (6).枚举;

      (7).回调;

      (8).迭代器和范围(ranges);

      (9).自定义运算符;

      (10).单继承和多继承;

      (11).STL数据结构;

      (12).具有引用计数的智能指针如std::shared_ptr;

      (13).具有正确引用计数的内部引用(Internal references with correct reference counting);

      (14).可以在Python中扩展具有虚(和纯虚)方法的C++类。

      pybind11支持的编译器

      (1).Clang/LLVM 3.3或更高版本;

      (2).GCC 4.8或更高版本:注:编译2.9.1版本的test,GCC需要5以上版本

      (3).Visual Studio 2015或更高版本。

      pybind11的安装

      (1).通过conda,执行:conda install -c conda-forge pybind11

      (2).通过pip,执行:pip install pybind11

      更详细文档介绍参考:https://pybind11.readthedocs.io/en/stable/index.html

      以下为测试代码:

      include/funset.hpp:C++代码头文件

#ifndef PYBIND11_FUNSET_HPP_
#define PYBIND11_FUNSET_HPP_#include <string>#define PYBIND11_API __attribute__((visibility ("default")))PYBIND11_API int get_random_number(int min, int max);struct PYBIND11_API Pet {Pet(const std::string& name) : name_(name) { }void setName(const std::string& name) { name_ = name; }const std::string& getName() const { return name_; }static int getAge() { return 18; }std::string name_;
};struct Dog : Pet {Dog(const std::string& name) : Pet(name) { }std::string bark() const { return "woof!"; }
};struct PolymorphicPet {virtual ~PolymorphicPet() = default;
};struct PolymorphicDog : PolymorphicPet {std::string bark() const { return "woof!"; }
};struct Pet2 {Pet2(const std::string& name, int age) : name_(name), age_(age) { }void set(int age) { age_ = age; }void set(const std::string& name) { name_ = name; }int getAge() const { return age_; }const std::string& getName() const { return name_; }std::string name_;int age_;
};struct Widget {int foo(int x, float y) { return 0; };int foo(int x, float y) const { return 1; };
};struct Pet3 {enum Kind {Dog = 0,Cat};struct Attributes {float age = 0;};Pet3(const std::string& name, Kind type) : name_(name), type_(type) { }std::string name_;Kind type_;Attributes attr_;
};#endif // PYBIND11_FUNSET_HPP_

      src/funset.cpp:C++代码的实现,编译生成动态库或静态库

#include "funset.hpp"
#include <random>
#include <iostream>PYBIND11_API int get_random_number(int min, int max)
{fprintf(stdout, "get random number through std::uniform_int_distribution\n");std::random_device rd;std::mt19937 generator(rd());std::uniform_int_distribution<int> distribution(min, max);return distribution(generator);
}

      example.cpp:生成python接口,编译生成动态库,若Python为3.8,则动态库名字为:example.cpython-38-x86_64-linux-gnu.so

#include <pybind11/pybind11.h>
#include <funset.hpp>// reference: https://pybind11.readthedocs.io/en/stable/namespace py = pybind11;// If you prefer the py::overload_cast syntax but have a C++11 compatible compiler only,
// you can use py::detail::overload_cast_impl with an additional set of parentheses
template <typename... Args>
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;// #define PYBIND11_MODULE(name, variable): name: module name; variable: a variable of type `py::module_` which can be used to initialize the module
PYBIND11_MODULE(example, m) {m.doc() = "pybind11 example plugin"; // optional module docstring// 1. bindings for a simple functionm.def("get_random_number", &get_random_number, "A function that get random number", py::arg("min"), py::arg("max"));// 2. bindings for a custom C++ data structure: class or struct// class_ creates bindings for a C++ class or struct-style data structurepy::class_<Pet>(m, "Pet")// init() is a convenience function that takes the types of a constructor’s parameters as template arguments and wraps the corresponding constructor.def(py::init<const std::string &>()).def("setName", &Pet::setName).def("getName", &Pet::getName)// Static member functions can be bound in the same way using class_::def_static().def_static("getAge", &Pet::getAge)// 3. Binding lambda functions.def("__repr__",[](const Pet &a) {return "<example.Pet named '" + a.name_ + "'>";})// We can also directly expose the name_ field using the class_::def_readwrite() method.// A similar class_::def_readonly() method also exists for const fields.def_readwrite("name", &Pet::name_);// 4. class inheritance// There are two different ways of indicating a hierarchical relationship to pybind11:// the first specifies the C++ base class as an extra template parameter of the class_:py::class_<Dog, Pet /* <- specify C++ parent type */>(m, "Dog").def(py::init<const std::string &>()).def("bark", &Dog::bark);// // Alternatively, we can also assign a name to the previously bound Pet class_ object and reference it when binding the Dog class// py::class_<Pet> pet(m, "Pet");// pet.def(py::init<const std::string &>())// 	.def_readwrite("name", &Pet::name);// // Method 2: pass parent class_ object:// py::class_<Dog>(m, "Dog", pet /* <- specify Python parent type */)// 	.def(py::init<const std::string &>())// 	.def("bark", &Dog::bark);// 5. class polymorphic// In C++, a type is only considered polymorphic if it has at least one virtual function and pybind11 will automatically recognize thispy::class_<PolymorphicPet>(m, "PolymorphicPet");py::class_<PolymorphicDog, PolymorphicPet>(m, "PolymorphicDog").def(py::init<>()).def("bark", &PolymorphicDog::bark);// Again, return a base pointer to a derived instance// Given a pointer to a polymorphic base, pybind11 performs automatic downcasting to the actual derived typem.def("pet_store2", []() { return std::unique_ptr<PolymorphicPet>(new PolymorphicDog); });// 6. Overloaded methodspy::class_<Pet2>(m, "Pet2").def(py::init<const std::string &, int>()).def("set", static_cast<void (Pet2::*)(int)>(&Pet2::set), "Set the pet's age").def("set", static_cast<void (Pet2::*)(const std::string &)>(&Pet2::set), "Set the pet's name").def("getAge", &Pet2::getAge).def("getName", &Pet2::getName);// If you have a C++14 compatible compiler, you can use an alternative syntax to cast the overloaded function// py::class_<Pet2>(m, "Pet2")// 	.def("set", py::overload_cast<int>(&Pet2::set), "Set the pet's age")// 	.def("set", py::overload_cast<const std::string &>(&Pet2::set), "Set the pet's name");// If a function is overloaded based on constness, the py::const_ tag should be usedpy::class_<Widget>(m, "Widget").def("foo_mutable", overload_cast_<int, float>()(&Widget::foo)).def("foo_const",   overload_cast_<int, float>()(&Widget::foo, py::const_));// 7. Enumerations and internal types: nested typespy::class_<Pet3> pet(m, "Pet3");pet.def(py::init<const std::string &, Pet3::Kind>()).def_readwrite("name", &Pet3::name_).def_readwrite("type", &Pet3::type_).def_readwrite("attr", &Pet3::attr_);py::enum_<Pet3::Kind>(pet, "Kind").value("Dog", Pet3::Kind::Dog).value("Cat", Pet3::Kind::Cat).export_values();py::class_<Pet3::Attributes>(pet, "Attributes").def(py::init<>()).def_readwrite("age", &Pet3::Attributes::age);
}

      build.sh:编译cpp文件生成动态库

#! /bin/bashreal_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}"
echo "dir_name: ${dir_name}"# build funset static library
# g++ -O3 -Wall -static -c -std=c++11 src/funset.cpp -Iinclude
# ar -r libfunset.a funset.o# build funset dynamic library
g++ -O3 -Wall -shared -fPIC -std=c++11 -o libfunset.so -c src/funset.cpp -Iincludeg++ -O3 -Wall -shared -std=c++11 -fPIC $(python3-config --includes) example.cpp \-o example$(python3-config --extension-suffix) \-L./ -lfunset \-I../../src/pybind11/include \-Iinclude# # delete funset library, example.cpython-38-x86_64-linux-gnu.so has contained relevant export symbols
rm libfunset*python test.py

      test.py:测试导出的python接口

import exampleprint("\n1.test simple function")
print("random number:", example.get_random_number(min=1, max=100))print("\n2.test class:")
p = example.Pet("Molly")
print("name:", p.getName())
p.setName("Charly")
print("name:", p.getName())
print("age:", p.getAge())
print("name:", p.name)
p.name = "Molly"
print("name:", p.name)print("\n3.test lambda function")
print("p:", p)print("\n4.test inheritance class:")
p = example.Dog("Molly")
print("name:", p.name)
print("bark:", p.bark())print("\n5.test polymorphic class:")
p = example.pet_store2()
print("type:", type(p))
print("bark:", p.bark())print("\n6.test overload methods:")
p = example.Pet2("Molly", 10)
p.set("Charly")
p.set(18)
print("name:", p.getName())
print("age:", p.getAge())print("\n7.test nested types")
p = example.Pet3("Lucy", example.Pet3.Cat)
print(f"type: {p.type}, value: {int(p.type)}")
print("Kind members:", p.Kind.__members__)

      执行结果如下:

      GitHub:https://github.com/fengbingchun/Python_Test

相关文章:

改善AI性别偏见的4种方法 | CSDN博文精选

加入「公开课」交流群&#xff0c;获取更多学习资料、课程及热招岗位等信息作者 | Josh Feast翻译 | 王子龙校对 | 王琦本文阐述导致AI偏见的原因并提出应用的解决方案。任何对AI偏见的审查都需要意识到一个事实&#xff1a;这些偏见主要源于人类固有的偏见。我们创建、训练的模…

C#程序调用外部程序

/**编程语言&#xff1a;VisualStudio.NetC#(Beta2)*作者&#xff1a;迪泊威*功能&#xff1a;通过C#程序调用Windows记事本程序编辑一个*名为test.txt的文本文件。**在整个程序中System.Diagnostics.Process.Start(Info)*为主要语句。*如果只是单独执行一个外部程序&#xff0…

svn 同步脚本

REPOS"$1"REV"$2"export LANGen_US.UTF-8/usr/bin/svn update /home/wwwroot/yswifi --username yangxc --password yangxc >>/tmp/svn_hook_log.txtecho who am i,$REPOS,$REV >> /tmp_hook_var.txt转载于:https://www.cnblogs.com/xkcp008/p…

DevOps火爆,招人却太难了!

DevOps一词最近两年人们谈的比较多&#xff0c;很多人简单地理解为“Dev”“Ops”&#xff0c;是否将开发人员和运营人员放在一个部门就完事了呢&#xff1f;其实DevOps是一组过程、方法与系统的统称&#xff0c;用于促进开发、技术运营和质量保障部门之间的沟通、协作与整合。…

网络数据包分析软件Wireshark简介

Wireshark是被广泛使用的免费开源的网络协议分析软件(network protocol analyzer)或网络数据包分析软件&#xff0c;它可以让你在微观层面上查看网络上发生的事情&#xff0c;它的功能是截取网络数据包&#xff0c;并尽可能显示出最为详细的网络数据包信息。它的源码在https://…

SEO研究:网站结构

在衡量所有权重之间&#xff0c;网站结构大概占到30%&#xff0c;这也是很多网站排名不好&#xff0c;或者有站长根本不用优化就能获得很好排名的原因。说到结构必须明白两个概念&#xff0c;一个是物理概念,就是文件存放的路径&#xff0c;另一个是逻辑结构。比较好的情况是逻…

form实现登陆操作

这几天想写个保存cookies的网页&#xff0c;先写了个登陆界面&#xff0c;奈何点击登陆后总是无法正常跳转。经查阅资料和询问高手&#xff0c;总算得以解决。 原错误代码如下&#xff1a; <html> <title>SaveCookies</title> <head> <script>fu…

深度学习中的优化算法之BGD

之前在https://blog.csdn.net/fengbingchun/article/details/75351323 介绍过梯度下降&#xff0c;常见的梯度下降有三种形式&#xff1a;BGD、SGD、MBGD&#xff0c;它们的不同之处在于我们使用多少数据来计算目标函数的梯度。 大多数深度学习算法都涉及某种形式的优化。优化指…

死宅福音:乐高不怕多,智能分拣机帮你归类

作者 | 神经小兮来源 | HyperAI超神经&#xff08;ID&#xff1a;HyperAI&#xff09;【导读】乐高现在几乎已经是优质玩具的代名词&#xff0c;该品牌旗下最为知名的&#xff0c;莫过于乐高积木。其丰富的形状与多样的玩法&#xff0c;无论大人小孩都喜欢。但是&#xff0c;这…

优化eclipse启动速度

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> 最近发现eclipse越来越慢&#xff0c;影响了开发使用速度。经过处理&#xff0c;快了一些&#xff0c;希望给大家一些提示。 1&#xff0c;取消系统的自动折叠 操作方法&#xff1a;…

一个基于J2EE的web应用程序运行起来需要什么?

2019独角兽企业重金招聘Python工程师标准>>> Eclipse &#xff1f;IDEA&#xff1f;这是目前市面上最常用的开发工具啦&#xff0c;我的理解是这些只是开发工具&#xff0c;是为了方便开发的&#xff0c;而不是web应用程序运行起来必须的东西。 为什么会有些这方面东…

深度学习中的优化算法之MBGD

之前在https://blog.csdn.net/fengbingchun/article/details/75351323 介绍过梯度下降&#xff0c;常见的梯度下降有三种形式&#xff1a;BGD、SGD、MBGD&#xff0c;它们的不同之处在于我们使用多少数据来计算目标函数的梯度。 大多数深度学习算法都涉及某种形式的优化。优化指…

华科提出目标检测新方法:基于IoU-aware的定位改进,简单又有效

作者 | 周强来源 | 我爱计算机视觉&#xff08;ID&#xff1a;aicvml&#xff09;【导语】近日&#xff0c;华中科技大学发表了一篇新论文《IoU-aware Single-stage Object Detector for Accurate Localization》&#xff0c;在此论文中作者提出了一种非常简单的目标检测定位改…

js init : function ()

这个init外面应该还有一层&#xff0c;比如 var a { init: function () {...}, exit: function () {...} } 这样的话&#xff0c;可以用a.init()来调用这个函数&#xff0c; <script type"text/javascript">var obj{init:function(str){alert("init调用&…

Google提出移动端新SOTA模型MixNets:用混合深度卷积核提升精度

作者 | Google译者 | 刘畅编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09; 【导语】目前&#xff0c;深度卷积&#xff08;Depthwise convolution&#xff09;在追求高性能的卷积网络中的应用变得越来越流行&#xff0c;但很多研究忽略了其内核…

桌面窗口的一些发现

最近因业务需要&#xff0c;玩了一下全屏问题。后来&#xff0c;对windows xp sp2的桌面窗口产生了兴趣。写了段代码&#xff0c;玩了一下。同时结合网上的一些知识&#xff0c;发现了以下一些现象。&#xff08;转载请指明出处&#xff09; 首先窗口名有#32769、Progman、Shel…

三说输入法[转]

如果我愿意&#xff0c;我会不停地说下去&#xff0c;直到烦死你们&#xff0c;谁让我用的输入法快呢。 我说了几句搜狗或股沟输入法的坏话&#xff0c;引来一些人的争论&#xff0c;大大在我预料之中&#xff0c;这年头&#xff0c;当你想说一些知名度较高的人或物的坏话时&am…

回忆之城市搜索

直接看效果点这里 HTML <!DOCTYPE html> <html> <head lang"zh-CN"><meta charset"utf-8"><title> 城市搜索 </title><link rel"stylesheet" href"ui-departure.css"> </head> <b…

ATL::CStringA和std::string之间转换的一些误区

对于刚做windows下VC的开发同学&#xff0c;类型转换应该是一个令其很苦恼的问题。我刚写工作的时候&#xff0c;也为这类问题不停的在网上搜索转换方法。最近工作中遇到一个“神奇”的bug&#xff08;一般“神奇”的问题往往是低级错误导致的&#xff09;&#xff0c;最后跟踪…

Windows XP鲜为人知的70招

一、Windows XP优化恢复Windows经典界面很多人安装了Windows XP后的第一感觉就是Windows变得漂亮极了。只是可惜美丽的代价要耗掉我们本就不富裕的内存和显存。要想恢复到和经典Windows类似的界面和使用习惯&#xff0c;请在桌面上单击鼠标右键&#xff0c;选择“属性”命令即可…

Github开源趋势榜Top 1:英伟达升级发布二代StyleGAN,效果更完美

整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;2018 年底&#xff0c;英伟达借鉴风格迁移的思路&#xff0c;提出当时最先进的无条件生成模型—— StyleGAN &#xff0c;吸引了大家广泛关注。随后&#xff0c;代码开源&#xff0c;一位 Uber …

百度地图 ip查询 service

官方文档&#xff1a;http://developer.baidu.com/map/wiki/index.php?titlewebapi/ip-api 请求 一个例子&#xff1a; http://api.map.baidu.com/location/ip?ak3GFi2F04wXaVuwmGu8fN49kL1234567890&ip180.161.128.181 返回 {"address": "CN|\u6cb3\u535…

python3编写简易统计服务器

打点这个功能总是美其名曰“帮助提升用户体验”&#xff0c;其实说白了就是记录用户做了哪些操作。目前国内很多通用软件都做了相关功能&#xff0c;像360、QQ等这样的以用户体验出众的软件&#xff0c;其打点的面自然也很广很细。当然这种“侵犯”用户隐私的事情在业内各个公司…

作价20亿美元!英特尔收购以色列AI芯片公司Habana Labs

出品 | AI科技大本营&#xff08;ID:rgznai1000&#xff09;12月16日&#xff0c;英特尔宣布以约 20 亿美元收购以色列公司Habana Labs&#xff0c;这成为英特尔在以色列仅次于 Mobileye&#xff08;153 亿美元&#xff09; 的第二大收购案。Habana Labs 成立于 2016 年&#x…

这就是奇客文化?简直太有才了!

这就是奇客文化&#xff1f;简直太有才了……

java中的char类型

2019独角兽企业重金招聘Python工程师标准>>> 一&#xff1a;char的初始化 char是Java中的保留字&#xff0c;与别的语言不同的是&#xff0c;char在Java中是16位的&#xff0c;因为Java用的是Unicode。不过8位的ASCII码包含在Unicode中&#xff0c;是从0~127的。 Ja…

[原创] 如何追踪每一笔记录的来龙去脉:一个完整的Audit Logging解决方案—Part I...

一、提出问题 在开发一个企业级 应用的时候&#xff0c;尤其在一个涉及到敏感数据的应用&#xff0c;比如财务系统、物流系统&#xff0c;我们往往有这样的需求&#xff1a;对于数据库中每一笔数据的添加、修改和删除&#xff0c;都需要有一个明确的日志&#xff0c;以便我们可…

进程间通信:同步双工管道

因为工作需要&#xff0c;需要设计出一个双工的IPC。&#xff08;转载请指明出处&#xff09;在一番比较后&#xff0c;我发现管道是比较符合我们的需求的。但是我们需求要求管道的对方是可信任的&#xff0c;而在vista以下系统是没有GetNamedPipeClientProcessId、GetNamedPip…

就因为一个笔记本,运营和产品吵得不可开交......

上班最讨厌的一件事情&#xff0c;莫过于开会&#xff0c;因为每次开会感觉就要吵架&#xff0c;这个今天开会又吵架了&#xff0c;吵架竟然是因为产品小姐姐的笔记本。产品小姐姐用了一本可擦笔记本记录会议内容&#xff0c;运营小姐姐竟然说这个本子有什么用&#xff0c;不就…

Ka的递归编程练习 Part4|Hanoi汉诺塔,双色汉诺塔的也有

1 #include <stdio.h>2 void hanoi(int s,char a,char b,char c) //a是出发盘&#xff0c;b是中途盘&#xff0c;c是结束盘 3 {4 if(s0) return;5 hanoi(s-1,a,c,b); //把最底下的从a借助c移动到b6 printf("%d from %c move to %c\n",s,a,c);7 …