环境信息:
$ lsb_release -aNo LSB modules are available.Distributor ID: UbuntuDescription: Ubuntu 20.04.2 LTSRelease: 20.04Codename: focal$ apt-get install python3-dev cmake g++
让我们首先为一个非常简单的函数创建Python绑定,该函数将两个数字相加并返回结果,为简单起见,我们将此功能和绑定代码都放入一个名为 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 docstringm.def("add", &add, "A function which adds two numbers");}
PYBIND11_MODULE() 宏创建一个函数,当从 Python 内部发出 import 语句时将调用该函数。 模块名称(示例)作为第一个宏参数给出(不应使用引号引起来);第二个参数 m 定义了 py::module_ 类型的变量,该变量是用于创建绑定的主要接口。 方法 module_::def() 生成将 add() 函数公开给Python的绑定代码。
关键字参数
通过简单的代码修改,就可以通知Python参数名称(在这种情况下为 i 和 j )。
m.def("add", &add, "A function which adds two numbers",py::arg("i"), py::arg("j"));
arg 是可用于将元数据传递到 module_::def() 的几种特殊标记类之一。 使用此修改后的绑定代码,我们现在可以使用关键字参数来调用函数,这是一种更具可读性的替代方法,特别是对于带有许多参数的函数:
import exampleexample.add(i=1, j=2)3L
关键字名称也出现在文档内的功能签名中:
help(example)....FUNCTIONSadd(...)Signature : (i: int, j: int) -> intA function which adds two numbers
也可以使用命名参数的简短表示法:
// regular notationm.def("add1", &add, py::arg("i"), py::arg("j"));// shorthandusing namespace pybind11::literals;m.def("add2", &add, "i"_a, "j"_a);
后缀 _a 构成一个C++11 字面量,它等效于 arg 。 请注意,必须首先通过使用引入命名空间 using namespace pybind11::literals 使 _a 运算符可见。 除了文字之外,这没有从 pybind11 命名空间引入任何其他内容。
默认参数
现在假设要绑定的函数具有默认参数,例如:
int add(int i = 1, int j = 2) {return i + j;}
默认值也出现在文档中。
>>> help(example)....FUNCTIONSadd(...)Signature : (i: int = 1, j: int = 2) -> intA function which adds two numbers
速记符号也可用于默认参数:
// regular notationm.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2);// shorthandm.def("add2", &add, "i"_a=1, "j"_a=2);
导出变量
要从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_answer42>>> example.what'World'
支持的数据类型
开箱即用地支持大量数据类型,它们通常可以无缝用作函数参数,返回值或通常与 py::cast 一起使用。有关完整概述,请参见“类型转换”部分。
