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

pybind11介绍相关推荐

  1. pybind11简单使用

    https://sanzo.top/Default/pybind11 pybind11介绍 github.com/pybind/pybind11 使用pybind11可以将C++库绑定到Python, ...

  2. python3 通过 pybind11 使用Eigen加速

    python是很容易上手的编程语言,但是有些时候使用python编写的程序并不能保证其运行速度(例如:while 和 for),这个时候我们就需要借助c++等为我们的代码提速.下面是我使用pybind ...

  3. pybind11 入门

    pybind 实例参考: https://github.com/tdegeus/pybind11_examples 函数名不能叫add,和系统的add冲突了,改个名可以. 参考:https://blo ...

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

    本文分享自华为云社区<混合编程:如何用pybind11调用C++>,作者:SNHer. 在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对 ...

  5. jvm jni 及 pvm pybind11 大批量数据传输及优化

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 环境说明 android 手机 linux python环境 前 ...

  6. 学习笔记 —— 基于C加速的Python高效计算 (Cython pybind11)

    目录 引言 Cython 示例介绍 第一阶段优化 第二阶段优化 Cython Annotation tool 优化方法 第三阶段优化 比对下 JIT的Numba 总结 pybind11 Links I ...

  7. torchscript相关知识介绍(二)

    一.TORCHSCRIPT 语言参考 1.TorchScript 是 Python 的静态类型子集,可以直接编写(使用@torch.jit.script装饰器)或者通过跟踪(tracing)从pyth ...

  8. 简单介绍互联网领域选择与营销方法

    在我看来,互联网领域的选择是"安家",而营销方法的不同则表现了"定家"的方式多种多样,只有选对了,"家"才得以"安定". ...

  9. 常用开源协议介绍以及开源软件规范列表

    1. 开源协议介绍 GPL: General Public License,开源项目最常用的许可证,衍生代码的分发需开源并且也要遵守此协议.该协议也有很多变种,不同变种要求会略微不同. MPL: MP ...

最新文章

  1. 编程实现算术表达式求值_用魔法打败魔法:C++模板元编程实现的scheme元循环求值器...
  2. response.getWriter()和jsp中out对象的区别
  3. 类的无参方法和Doc注释
  4. Java SecurityManager checkPackageDefinition()方法与示例
  5. Go Web 编程--应用 ORM
  6. 【深度优先搜索】计蒜客:正方形
  7. errno是否是thread safe的
  8. 淘宝全屏雪花特效页面
  9. 数学分析教程(科大)——2.5笔记+习题
  10. 海航科技集团要寻人才去火星喽!
  11. 关于MNN中图像预处理
  12. 晚风心里吹-粤语歌词谐音
  13. Unreal Engin_画廊制作笔记_001<设计草图,利用BSP快速搭建简单场景>
  14. 关于com.lowagie.text包的报错问题
  15. 计算机系的对联,首个计算机对联系统问世
  16. java实现红包要多少钱_java实现微信红包分配算法
  17. PHP根据身份证号码获取户口所在地
  18. Vue前台两级下拉栏分类内容
  19. 1039 到底买不买 (20 分)
  20. centos7: 启动vpp报错:Main heap allocation failure

热门文章

  1. LeetCode刷题记录14——257. Binary Tree Paths(easy)
  2. mysql8.0.12密码_mysql8.0.12如何重置root密码
  3. opencv中ArUco模块实践(1)
  4. Intro to Parallel Programming CUDA-第一单元
  5. 在Ubuntu 14.04 64bit中永久添加DNS的方法
  6. Unity制作2D动作平台游戏视频教程
  7. Blender从头到尾创建一个低多边形场景学习教程
  8. 3D场景高级合成技术学习
  9. ceph bluestore 源码分析:ceph-osd内存查看方式及控制源码分析
  10. ubuntu自定义命令