我们继续讨论如何从Python3调用C / C ++的主题 。 现在,我们使用C API创建模块,在此示例中,我们可以弄清楚cffi和其他库如何简化我们的生活。 因为我认为这是最困难的方法。
ç
一个测试库,用于演示如何使用带有各种类型参数的全局变量,结构和函数。 在我的文章中,根据我现在使用的方法,我使用同一库的变体。 链接到下面的以前的方法。
测试
typedef struct test_st_s test_st_t; extern int a; extern double b; extern char c; static PyObject *func_hello(PyObject *self, PyObject *args); static PyObject *func_ret_int(PyObject *self, PyObject *args); static PyObject *func_ret_double(PyObject *self, PyObject *args); static PyObject *func_ret_str(PyObject *self, PyObject *args); static PyObject *func_many_args(PyObject *self, PyObject *args); static PyObject *func_ret_struct(PyObject *self, PyObject *args); struct test_st_s { PyObject_HEAD
测试
要求该模块指出它将包括:函数,全局变量和结构。 每个这样的东西都需要描述,对于它的数据类型(结构...)来说是最困难的事情。大约这样的文件是由cffi生成的。
要工作,必须连接头文件:
#include <Python.h> #include <structmember.h> //
编译标志:
$(python3-config --includes --ldflags) -fPIC
以下函数负责处理参数:
PyArg_ParseTuple(args, "ids", &val1, &val2, &val3);
第一个是int类型的参数,它的字母名称为i
2nd float / double- d
第三弦-s
可以在此处找到所有可能的数据类型字母指定。
现在我们转向如何描述结构的描述。
struct.c:
这就是为了:
struct test_st_s { PyObject_HEAD
同意一点。 此外,可以为该结构定义方法(例如, test_st_print )。
在代码中,我尝试增加注释以减少描述。
巨蟒
使用Python中的C模块的示例:
import sys import time
该模块已成为本地模块。
C API的优缺点
优点 :
缺点 :
- 难以用C API描述您的数据类型
- 纯粹的程序员很难为Python实现,也不是对他们来说……(对我来说,最简单的方法是通过ctypes )
- 模块(库)仅适用于Python
每个方法从1000开始的平均测试执行时间为:
- ctypes:-0.0004987692832946777秒-
- CFFI:-0.00038521790504455566秒-
- pybind:-0.0004547207355499268秒-
- C API:-0.0003561973571777344秒-
参考文献