0.简介
为什么在Python中调用C代码?
1.提升代码运行速度
2.C语言中的传统类库
3.从内存到文件接口的底层资源访问
有哪些方法?
1.-ctypes
2.SWIG
3.Python/C API
1.CTypes
使用Python中的ctypes模块是最为简单的。ctypes提供了和C兼容的数据类型和函数来加载dll文件,因此在调用时不需要对源文件做任何修改。
下面是例子:
1.1 建立C函数
1 | #include <stdio.h> |
1.2 将C语言编译为.so文件(windows下为dll),生成adder.so文件。
1 | #For Linux |
1.3 在Python代码中调用C函数
1 | from ctypes import * |
在这个文件中,C语言是自解释的。
在Python文件中,一开始先导入ctypes模块,然后使用CDLL函数来加载我们创建的库文件。这样我们就可以通过变量adder来使用C类库中的函数了。当adder.add_int()被调用时,内部将发起一个对C函数add_int的调用。ctypes接口允许我们在调用C函数时使用原生Python中默认的字符串型和整型。
而对于其他类似布尔型和浮点型这样的类型,必须要使用正确的ctype类型才可以。如向adder.add_float()函数传参时, 我们要先将Python中的十进制值转化为c_float类型,然后才能传送给C函数。这种方法虽然简单,清晰,但是却很受限。例如,并不能在C中对对象进行操作。
2.SWIG(Simplified Wrapper and Interface Generator)
这个方法需要编写额外的接口文件来作为SWIG的入口,一般不使用这个方法,因为比较复杂。但是,当你一个C/C++代码库需要被多种语言调用时,这就很有用了。
例子:
1 | //example.c |
编译:
1 | unix % swig -python example.i |
输出:
1 | >>> import example |
3.Python/C API
最广泛使用的方法,不仅简单而且可以在C代码中操作Python对象。
这种方法需要以特定的方式来编写C代码以供Python去调用它。所有的Python对象都被表示为一种叫做PyObject的结构体,并且Python.h头文件中提供了各种操作它的函数。例如,如果PyObject表示为PyListType(列表类型)时,那么我们便可以使用PyList_Size()函数来获取该结构的长度,类似Python中的len(list)函数。大部分对Python原生对象的基础函数和操作在Python.h头文件中都能找到。