pybind11中文资料(第四章 第一步)

在此我要特别感谢pybind11项目创立者 Wenzel Jakob以及众多项目参与者

4 第一步

本节演示了pybind11的基本功能。在开始之前,请确保已设置开发环境并编译测试用例集。

4.1 编译测试用例

4.1.1Linux/MacOS

Linux系统,需要安装python-devpython3-dev软件包以及cmake。Mac OS,包含的python版本可直接使用,但仍然必须安装cmake

安装必备组件后,执行

mkdir build

cd build

cmake ..

make check -j 4

最后一行将编译并且运行测试

 

4.1.2windows

Windows上,仅支持Visual Studio 2015及更高版本,因为pybind11依赖于各种C ++ 11语言功能,而这些特性会破坏旧版本的Visual Studio

编译并运行测试

mkdir build

cd build

cmake ..

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

这将完全用命令行,创建一个Visual Studio项目,编译并运行目标。

Note:

如果所有测试都失败,请确保python二进制文件和测试用例在相同的处理器类型和系统位宽(i386x86_64编译。你可用cmake -A x64 .. 命令指定x86_64作为Visual Studio项目的体系结构。

See also:

熟悉Boost.Python的高级用户可能希望跳过教程并查看test目录中的测试用例,该测试用例运用了pybind11的所有特性。

4.2头文件和命名空间约定

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

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

某些功能可能需要其他头文件,但会根据需要指定。

4.3为简单函数创建绑定

首先从为一个简单的函数创建Python绑定开始,函数计算两个数字之和并返回的结果:

int add(int i, int j) {

return i + j;

}

为简单起见[1],这个函数和绑定代码放在example.cpp文件中,文件内容如下:

#include <pybind11/pybind11.h>

int add(int i, int j) {

return i + j;

}

PYBIND11_MODULE(example, m) {

m.doc() = "pybind11 example plugin"; // optional module docstring

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

}

[1]实际上,实现和绑定代码通常位于单独的文件中。

PYBIND11_MODULE()宏创建了一个函数,当Python代码import相应模块时将调用该函数。模块名(example)作为第一个宏参数给出(不需要用引号包含)。第二个参数(m)定义了一个py::module类型的变量,它是创建绑定的主要接口。方法module::def()将生成add()函数的Python的绑定代码。

Note:

注意到只要少量的代码就可以将函数暴露给Python:所有跟函数入参和返回值的细节由模板元编程自动推断。这种方法和语法是从Boost.Python中借用的,尽管底层实现是完全不同的。

pybind11是一个只有头文件的库,因此没有必要链接任何特殊的库,也没有中间转换步骤。在Linux系统中,可以使用以下命令编译上面的示例:

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

如果需要更多有关于Linux和MacOS上所需编译标志的详细信息,请参阅手动构建。有关完整的跨平台编译说明,请参阅 构建系统 页面。

python_examplecmake_example库也是很适合初学者的。它们都是具有跨平台构建系统的完整项目示例。两者之间的唯一区别是python_example使用Python的setuptools构建模块,而cmake_example使用CMake(这应该是已有的C ++项目的首选)。

构建上述C ++代码将生成可导入Python的二进制模块文件。假设已编译的模块位于当前目录中,以下交互式Python会话将显示如何加载和执行该示例:

$ python
Python 2.7.10 (default, Aug 22 2015, 20:33:39)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.add(1, 2)
3L
>>>

4.4关键字参数

只要对代码稍加改动,就可以通知Python有关参数的名称(例如本例中的“i”和“j”)。

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

arg是可用于将元数据传递到module::def()的几个特殊标记类之一。使用这个修改后的绑定代码,我们可以使用关键字参数来调用函数,这更具可读性,特别是带有许多参数的函数。

>>> import example
>>> example.add(i=1, j=2)
3L

关键字名称也出现在文档中的函数签名中。

>>> help(example)
....

FUNCTIONS
    add(...)
        Signature : (i: int, j: int) -> int

        A function which adds two numbers

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

// regular notation
m.def("add1", &add, py::arg("i"), py::arg("j"));
// shorthand
using namespace pybind11::literals;
m.def("add2", &add, "i"_a, "j"_a);

_a后缀形成C++11字面量就相当于arg。请注意,这种操作必须首先声明using namespace pybind11::literals。除了literals,这不会从命名空间内引入其他内容。

4.5默认参数

现在假设要绑定的函数具有默认参数,例如:

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

不巧的是,pybind11无法自动提取这些参数,因为它们不是函数类型信息的一部分。但是,使用以下arg来指定它们:

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

默认值也出现在文档中。

>>> help(example)
....

FUNCTIONS
    add(...)
        Signature : (i: int = 1, j: int = 2) -> int

        A function which adds two numbers

简写符号也可用于默认参数:

// regular notation
m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2);
// shorthand
m.def("add2", &add, "i"_a=1, "j"_a=2);

4.6导出变量

为了暴露C++变量,需要使用attr函数在模块中注册它,做法如下。内置类型和常规对象(稍后将详细介绍)在分配为属性时会自动转换,并且可以使用py::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'

4.7支持的数据类型

原生支持大量数据类型,可以无缝地用作函数参数,通常直接返回值或者经过py::cast处理再返回。有关完整概述,请参阅类型转换部分。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值