Python调用C/C++里的函数
Python调用C语言的函数主要分为三部分:标准的C语言函数库、C语言Python调用模块(wrapper)、和标准的Python调用。
标准C语言函数库
里面有一系列的C语言函数。
1 | int add(int m, int n) |
标准Python调用
1 | python |
C语言Python调用模块
C语言Python wrapper,python原生代码可以通过这个wrapper来调用C语言函数文件里的函数。
这个模块分为三部分:导出函数、方法列表和初始化函数。
1 | /* Exported function */ |
导出函数
连接C语言函数和Python函数的中间件,由它来进行相互转换。把Python的参数转成C的参数传递过去,然后再把C的输出转换成Python格式返回。
- 转换Python参数为C语言类型
该函数的第二个参数args
就是原生Python调用传递过来的参数,是一个C的Python Tuple Object,需要转换成标准的C语言数据类型。简单的参数可以使用PyArg_ParseTuple
函数来进行解析,其中第二个参数是C语言中的类型表示符,示例中的意思是这个Python传过来的参数包含两个整型(int)数值并且分别赋值给m和n。
复杂点的参数就需要用PyTuple_GetItem
进行解析了,比如args分别包含了一个int型和一个字典类型数据就需要如下操作:
1 | int m; |
此处的PyObject dict又可以使用PyDict_GetItemString(dict, key)来解析,如果这个dict的key不是字符串,可以使用PyDict_GetItem(dict, PyObjectKey)。
- 转换C语言数据为Python类型并返回
简单的C语言数据可以使用Py_BuildValue
来转换,示例中obj = Py_BuildValue("i", ret)
意思就是将ret转换成Python的int Object。
复杂的(比如返回值类型是list)可以用PyList_SetItem
来转换,如这个返回的list中第一个值是字符串第二个是dict:
1 | PyObject *list = NULL; |
在ParseTuple和Py_BuildValue中可以使用的C类型
方法列表和初始化函数
你C函数库中所有函数都需要写到这里面,如下:
1 | static PyMethodDef CalMethods[] = { |
编译链接
1 | gcc -fpic -c -I /usr/include/python2.7 \ |
gdb默认优化了编译选项,这会导致你调试时出现行号不对的问题,这时你需要在gcc编译时加上-O0
来禁用优化来保证调试时行号与源文件保持一致。
gdb调试python脚本及c module
1 | gdb python |