pybind11中⽂资料(第四章第⼀步)
在此我要特别感谢pybind11项⽬创⽴者 以及众多项⽬参与者
4 第⼀步
本节演⽰了pybind11的基本功能。在开始之前,请确保已设置开发环境并编译测试⽤例集。
4.1 编译测试⽤例
4.1.1Linux/MacOS
Linux系统,需要安装python-dev或python3-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⼆进制⽂件和测试⽤例在相同的处理器类型和系统位宽(i386或x86_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;
}
为简单起见,这个函数和绑定代码放在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的setuptools构建模块,⽽使⽤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);cmake如何使用
// 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处理再返回。有关完整概述,请参阅类型转换部分。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论