Python调用C++之PYBIND11源码分析

前情提要

在之前的文章Python调用C++之PYBIND11简介中我们介绍了pybind11的基本用法,我们已经知其然,接下来我们通过代码分析,知其所以然。通过之前的讲解,我们知道使用pybind11去导出C++接口到Python,只要使用一个宏PYBIND11_MODULE,例如之前的例子,将已有的C++函数int add(int, int)导出到Python:

#include "existence.h"
#include <pybind11/pybind11.h>

PYBIND11_MODULE(example, m) {
   
    m.doc() = "pybind11 example plugin"; // optional module docstring
    m.def("add", &add, "A function which adds two numbers");
}

我们知道,用传统方法编写C++扩展模块的方法主要有以下几步,对于Python2和Python3,方法略有不同:

Python2
  1. 拥有一个需要导出到Python的C++接口;
  2. 将这个C++接口用一个PyMethodDef结构体封装起来,构成一个方法表,如果使用PyModule_AddObject这一步是不需要的;如果将PyModuleDef比作车头,PyMethodDef比作车厢,两种方法的区别就相当于是PyModule_AddObject()先把车厢挂在车头上在网上装货物,而手动封装PyMethodDef`就是先装了货物在将车头链接上;
  3. 调用Py_InitModule(name, PyMethodDef**)得到一个模块对象,假设叫做m
  4. 调用PyModule_AddObject(m, name, PyObject*)将函数添加到模块;或者调用Py_InitModule去装载第二步中封装的方法表;
  5. 给出一个按一定规则命名的函数供Python解析器加在该模块的时候调用,这个函数名的命名规则是特定前缀 + 模块名。Python 2的是init。例如,initexample,其中example是模块名。作用是调用第四步中的两个函数之一去盘活整个创建过程。
Python3
  1. 拥有一个需要导出到Python的C++接口;
  2. 将这个C++接口用一个PyMethodDef结构体封装起来,构成一个方法表,如果使用PyModule_AddObject()这一步是不需要的。如果将PyModuleDef比作车头,PyMethodDef比作车厢,两种方法的区别就相当于是PyModule_AddObject()先把车厢挂在车头上在网上装货物,而手动封装PyMethodDef`就是先装了货物在将车头链接上;
  3. 将第二步方法表使用PyModuleDef结构体封装;
  4. 根据PyModuleDef种的内容初始化模块,调用PyModule_Create(PyModuleDef*)函数创建模块;
  5. 给出一个按一定规则命名的函数供Python解析器加在该模块的时候调用,这个函数名的命名规则是特定前缀 + 模块名。Python 3 的特定前缀是PyInit_。例如,PyInit_example,其中example是模块名。

总结就是,一个表示模块的对象,一个表,表的每一行用来表示模块拥有的一个方法对象,在模块初始化的时候,解析器找到一个特殊名字的方法,这个方法负责生成一个模块对象和填充表格的内容,这两件事谁先谁后并没有影响。

相比于使用Python官方介绍的方法,pybind11只用两三行代码就完成了工作,简直不要太爽。关于使用传统方法去导出C++接口,我在使用C语言编写Python模块-引子也有介绍过,没看过的可以去看一看,它是我们能看懂pybind11源码的基础。

正文

万变不离其宗,pybind11只不过是将原本我们所需要做的封装好了而已,下面我们就来揭开它神秘的面纱。首先,我们来看看宏PYBIND11_MODULE定义,它所依赖一些宏我也一并找出并列了出来:

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值