pybind11学习 迈出第一步
本文主要记录官方文档中FIRST STEPS一章的学习笔记。
[TOC]
1 简单函数的绑定
先从一个简单的示例开始:
1 |
|
在这段C++代码中,我们定义了一个简单的加法函数add
,并创建其的Python绑定。下面我们详细讲解一下创建绑定部分的代码。
PYBIND11_MODULE
可以看作一个函数,作用是创建一个Python模块(可以在Python中import
)。PYBIND11_MODULE
有两个参数,第一个是模块名称(example);第二个是类型为py::module_
的变量(m),它是创建绑定的主要接口。module_::doc()
方法(可选),用于生成模块的描述文档。module_::def()
方法,用于生成C++函数的Python绑定。module_::def()
方法源码定义如下:
1 |
|
参数如下:
- **name_**:绑定后函数在模块中的名称。
- f:被绑定的C++函数。
- extra:可变参类型,额外参数。(示例中是字符串,用于生成绑定函数的描述文档。)
为了验证上面的解释,我们将在VS中编译生成的pyd文件import到Python,执行如下控制台交互操作:
1 |
|
2 关键字参数
在上面示例的基础上进行如下修改,我们就可以实现指定关键字参数(即参数的名称)。
1 |
|
是可用于将元数据传递到module_::def()
的几个特殊标记类之一。使用上面修改后的代码,我们可以在调用函数时使用关键字参数,以增加代码可读性,特别是对那些带有多个参数的函数。
1 |
|
修改前,我们在Python解释器中help(example.add)
,函数签名如下:
add(arg0: int, arg1: int) -> int
修改后,函数签名如下:
add(i: int, j: int) -> int
还可以使用更加简洁的方式给参数命名:
1 |
|
后缀_a
会生成一个等价于py::arg
类的字面量。
3 默认参数
若需要绑定如下带有默认参数的C++函数。
1 |
|
pybind11不能自动地提取默认参数,因为它不属于函数类型信息的一部分。我们需要借助py::arg
来实现这一功能:
1 |
|
查看函数签名:add(i: int = 1, j: int = 2) -> int
。
简化写法:
1 |
|
4 变量的绑定
我们可以使用module_::attr()
方法来注册需要导出到Python模块中的C++变量。内建类型和常规对象(在类型转换一章会讲到)会在指定attriutes
时自动转换,也可以使用py::cast
来显式转换。
1 |
|
在Python中使用变量:
1 |
|
5 总结
pybind11的局限性
我们在编译链接用pybind11创建Python绑定的C++源码时,会指定链接器中python解释器的动态库(如python38.lib)。这样生成的二进制文件(如.pyd模块文件)只能导入到解释器同样为python3.8的代码中,否则会报错
ImportError: Module use of python38.dll conflicts with this version of Python.
。数据类型转换
在上面示例中,我们绑定的函数中参数类型都比较常规(比如int),这种参数类型在Python和C++中能够很好的识别和传递,都会自动转换。函数参数值是通常是直接返回或经过
py::cast
显式转换后再返回。
参考
官方文档中文翻译:pybind11-Chinese-docs: pybind11中文文档
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!