Python C 扩展示例 & 99宿舍加密算法

一、写在前面

1、我们可以用 C 语言为 Python 写一些模块以便提升运行效率,下面我们就用‘99宿舍’四六级成绩查询加密算法的例子来简单介绍一下 python2 的 C 扩展基本结构。

2、‘99宿舍’客户端使用 DES_CFB64 算法来加密 HTTP 通讯数据。另外,加密发送数据、解密接收到的数据使用的是不同的 key ,具体可以通过逆向获取。

二、C 模块的基本框架

1、导出函数的结构

先介绍一段代码中执行逻辑处理的代码,比如我们的功能就是返回“Hello,World”字符串:

这里有两个函数,普通的 C 函数 do_foo() 和 可被 Python 接口识别调用的 foo()
注意传递的参数列表:(PyObject* self, PyObject* args), 还有其他两种格式,具体我们在第三节解释

2、函数列表/注册函数

我们通过一个数组记录上面写好的导出函数/接口,这个就是 static PyMethodDef ExtendMethods[],示例代码:

PyMethodDef 结构体的定义:

针对 'int ml_flags' 这个field,后面再详细介绍

3、模块初始化

调用 Py_InitModule() 来初始化/注册模块,另外调用Py_InitModule()的函数需要被 PyMODINIT_FUNC 所修饰
PyMODINIT_FUNC 的定义在 /usr/include/python2.7/pyport.h 中,在 C 里面为void,C++ 里面则是extern "C"
示例代码:

 

三、C 接收 Python 对象作为参数

1、导出函数申明

对于如何接受参数以及接受什么样的参数,主要有以下三种格式:

本文没有涉及第三种传递关键词参数的介绍,具体可以参考:https://docs.python.org/2/extending/extending.html#keyword-parameters-for-extension-functions

2、注册函数时的 flag

上面的三种参数格式,在 函数列表 ( PyMethodDef [] ) 中注册函数对应的三种 flag 选择如下:

3、Python 对象转换为 C 的基本类型

我们需要将 PyObject* args 里面包含的参数转换为 C 语言里面对应的基本类型,我们使用的函数是:int PyArg_ParseTuple(PyObject *args, const char *format, ...)
其他方法和支持的变量类型请见:https://docs.python.org/2/c-api/arg.html
示例代码:

 

四、C 返回值转为 Python 对象

1、返回非空值

使用 PyObject* Py_BuildValue(const char *format, ...) 构造返回值

如果 char *format 字符串为空,则返回None;
如果 char *format 字符串仅包含一个元素,则返回的对象类型就是那个元素的类型;
如果 char *format 字符串为多个元素,则返回一个 tuple

具体支持的变量类型:https://docs.python.org/2/c-api/arg.html#c.Py_BuildValue
示例代码:

2、返回空值

 

五、完整的 DES_CFB64 模块实现

1、des_cfb64.h

2、des_cfb64.c

3、desdemo.c

六、编译&链接

1、手写 Makefile 编译生成动态链接库

运行命令 make  编译生成 so 文件,然后在当前目录下启动python,import desdemo 即可

2、使用 python 推荐的 setup.py

准备好 setup.py,python setup.py build 进行编译,然后进入build/lib* 目录找到 .so 文件,即可import使用
或者使用 python setup.py install 将 .so 文件安装到python系统路径里(需要root权限)

 

七、参考资料

1. Python 文档:模块编写 https://docs.python.org/2/extending/extending.html
2. Python 文档:参数处理 https://docs.python.org/2/c-api/arg.html#c.PyArg_ParseTuple
3. IBM DeveloperWorks: 用C语言扩展Python的功能
4. 使用C写Python的模块:https://www.zouyesheng.com/python-module-c.html
5. Python 文档:setup脚本 https://docs.python.org/2/distutils/setupscript.html
6. cnblog: 使用C语言扩展Python(一)

发表评论

电子邮件地址不会被公开。 必填项已用*标注