文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

跟我一起学习pybind11 之一

2023-01-31 08:19

关注

pybind11是一个轻量级的“Header-only”的库,它将C++的类型暴露给Python,反之亦然。主要用于将已经存在的C++代码绑定到Python。pybind11的目标和语法都类似于boost.python库。利用编译时的内省来推断类型信息。

boost.python最大问题在于,boost太过复杂和庞大。pybind11除去注释,代码仅仅4000多行,需要依赖Python2.7或Python3。

支持的编译器

  1. Clang/LLVM (any non-ancient version with C++11 support)
  2. GCC 4.8 or newer
  3. Microsoft Visual Studio 2015 or newer
  4. Intel C++ compiler v17 or newer

介绍pybind11的基本特性。

编译测试用例

Linux/MacOS

需要安装python-dev或者python3-dev、cmake。

mkdir build
cd build
cmake ..
make check -j 4

最后一行命令make check -j 4将会编译并自动执行测试用例。

Windows

仅仅支持Visual Studio 2015以及更新的版本。

mkdir build
cd build
cmake ..
cmake --build . --config Release --target check

以上命令将会创建一个Visual Studio工程,并且该工程将会被自动编译。

注意:如果所有的测试都失败了,请确保Python二进制类型和测试用例被编译的二进制类型与处理器类型匹配。

头文件和命名空间

为了简洁起见,所有的示例都将假设存在以下两行代码:

#include <pybind11/pybind11.h>
namespace py = pybind11;

某些功能也许需要其它更多的头文件,但是那些部分将在需要时列出来。

绑定简单函数

让我们以一个极度简单的函数来开始创建python绑定,函数完成两数相加并返回结果

int add(int i, int j)
{
    return i + j;
}

为简单起见,我们将函数和绑定代码都放在example.cpp这个文件中

#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"; // 可选的模块说明

    m.def("add", &add, "A function which adds two numbers");
}

PYBIND11_MODULE()宏函数将会创建一个函数,在由Python发起import语句时该函数将会被调用。模块名字“example”,由宏的第一个参数指定(千万不能出现引号)。第二个参数"m",定义了一个py::module的变量。函数py::module::def()生成绑定代码,将add()函数暴露给Python。


注意:仅仅只需要少量的代码就能完成C++到Python的绑定工作,所有关于函数参数、返回值的细节,将会被模板元编程自动推导出来!这种整体的方法和语法都借鉴了Boost.Python,但是其底层实现是完全不同的。


pybind11是一个“header-only”的库,因此不需要链接(依赖)任何库,也没不需要任何的转换步骤。例如在Linux中,这个例子可以直接使用以下命令来编译:

c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example `python3-config --extension-suffix`

对于完整的跨平台的指令,详情请参考“构建系统(build systems)”章节

该例子被构建完成之后,将会生成一个可以被导入(import)到Python的二进制模块。被编译的模块位于当前目录,下面将展示如何在Python回话中使用刚刚生成的模块:

import example
example.add(1, 2)

关键字参数

(针对前一个例子)做一个简单修改,它将使得告知Python关于参数的名字成为可能(在本例中就是“i"和”j“)

m.def("add", &add, "A function which adds two numbers", py::arg("i"), py::arg("j"));

py::arg是众多特殊标签之一,它们能将元数据(metadata)传递给py::module::def()。通过这个简单的修改,我们可以利用“keyword arguments”来调用函数了。这在多参数的场景下,是一个更具可读性的方案。下面将展示如何在Python中使用“keyword arguments”:

import example
# 参数的名字也将出现在文档的函数签名中。
help(example)
example.add(i=1, j=2)

还可以用较短的命名参数表示法:

    using namespace pybind11::literals;
    m.def("add2", &add, "i"_a, "j"_a);

_a后缀是一个C++11的字面字,与py::arg是等价的。

默认参数

现在假设函数具有默认参数:

int add(int i = 1, int j = 2)
{
    return i + j;
}

不幸的是,pybind11不能自动地提取这些参数,因为他们(默认参数)不是函数的类型信息。不过可以利用py::arg扩展来很很简单的实现这些特性。下面例子将展示pybind11对默认参数的支持:

PYBIND11_MODULE(example, m)
{
    m.doc() = "pybind11 example plugin"; // 可选的模块说明
    // default argument
    m.def("add3", &add, "A function which adds two numbers", py::arg("i") = 1, py::arg("j") = 2);
}

现在在python中使用带默认参数的add函数:

>>> import example
>>> help(example.add3)
Help on built-in function add3 in module example:

add3(...) method of builtins.PyCapsule instance
    add3(i: int = 1, j: int = 2) -> int

    A function which adds two numbers

>>> example.add3()
3
>>> example.add3(3)
5
>>> example.add3(j=3)
4
>>>

导出变量

在pybind11通过py::module::attr() 函数实现从C++中导出变量到Python中。内建的类型和泛型对象在被指定为属性(attribute)时将会被自动的转换,同事也可以使用函数py::module::cast进行显示的转换。

PYBIND11_MODULE(example, m)
{
    m.attr("the_answer") = 42;
    py::object world = py::cast("World");
    m.attr("what") = world;
}

下面的示例将展示如何在Python中访问导出的变量:

>>> import example
>>> example.the_answer
42
>>> example.what
'World'
>>>
>>> example.the_answer = 100
>>> example.the_answer
100
>>>

支持数据类型

大量可以开箱即用的数据类型,可以无缝地用作函数参数、返回值或者被py::cast用来转换。这部分内容将在类型转换章节(Type conversions)进行介绍。


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯