以下为授权转载的一盎司科技公众号文章
PyBind11是一个轻量级的C++库,主要用于创建现有C++代码的Python绑定,使用了很多C++新特性。
下面将介绍一些PyBind11日常会用到的一些功能点,如分拆转换文件,类的纯虚函数使用,函数重载等,关于PyBind11的详细内容可参考官方文档(https://pybind11.readthedocs.io/en/stable/)。
示例代码地址:
GitHub地址:https://github.com/iounce/python-cpp-demo
Gitee地址:https://gitee.com/iounce_admin/python-cpp-demo
环境
-
Windows操作系统:Windows10(21H2,19044.1766)
-
C++开发环境:Visual Studio 2022社区版
-
Python:3.10.4
-
PyBind11:2.11.1
分拆转换文件
为了规范以及方便管理,通常可以将转换内容分拆到多个文件之中,然后在主转换文件中引用即可,参考上一篇的例子,作如下分拆:
-
func.h里面的函数添加到python_func.h转换文件中
-
bird.h里面的函数添加到python_bird.h转换文件中
-
主转换文件python_api.cpp引用python_func.h和python_bird.h文件
定义类纯虚函数
在文件class.h中,定义抽象类Base,包含protected访问的纯虚函数valid(),具体如下:
编写转换文件python_class.h,增加对纯虚函数valid()的转换。由于抽象类无法实例化,需要借助自定义类实现转换操作。首先定义PyBase类,继承Base类,作为新的基类。然后再新增PyPublicBase类,将protected访问的valid函数改为public,这样可以直接在外部访问。具体如下:
定义类静态变量
简单起见,定义public访问的静态变量,具体如下:
在转换文件中,需要增加特别标记def_readwrite_static来定义静态变量,具体如下:
定义类重载函数
定义set()函数,分别设置整形和字符串类型的入参,具体如下:
在转换文件中,需要增加特别标记overload_cast来定义重载函数,具体如下:
定义类指针数组函数
定义parse函数,类似main函数的入参,具体如下:
在编写转换函数过程中,首先需要调整入参,譬如main函数,一般来说只是传递空格分隔的参数,而无需设置参数个数,所以在python调用过程中传递字符串list即可。此处增加std::vector和Python中list的转换,计算出参数个数再传递给C++函数。具体如下:
编写Python测试程序
首先在主转换文件添加类的转换文件python_class.h,然后初始化,具体如下:
编译生成Python包后,先将生成的文件pybind11_demo.cp310-win_amd64.pyd(环境不同生成文件名可能有差异)拷贝到当前目录,然后编写测试程序main.py并执行:
说明:由于Base类为虚基类,故需要定义子类来继承后使用,如Derive类。