python3与C/C++语言混合编程,是一个常用的协作方式,可以结合Python3的方便及强大的库与C/C++的高效与快捷。
混合编程时C语言文件需要提供以下几部分的支持:
- //func.c
-
- #include
//包含Python.h头文件,以引入python的数据结构 - #include
-
- #define NULL 0
-
- //C语言的功能实现函数
- static int do_add(int a, int b)
- {
- int sum = a + b;
- printf("c call do_add, %d + %d = %d\n", a, b, sum);
- return sum;
- }
-
- //Python的模块接口函数
- static PyObject* add(PyObject *self, PyObject *args)
- {
- int a = 0, b = 0;
- if(!PyArg_ParseTuple(args, "ii", &a, &b)) //通过PyArg_ParseTuple获得Python模块调用时,传递的函数参数
- {
- return NULL;
- }
- int result = do_add(a, b); //调用C语言功能实现函数,完成具体的功能
- return Py_BuildValue("i", result); //构建PyObject对象作为返回值
- }
-
- //Python接口映射函数
- /* 关于参数{ "add", (PyCFunction)add, METH_VARARGS, "add" }的说明
- 第一个参数:为此模块对外提供的接口函数的名字
- 第二个参数:为接口函数的函数指针
- 第三个参数:一般是METH_VARARGS;
- 如果想传入关键字参数,可以与MET_KEYWORDS进行或运算;
- 如果不接受任何参数,可以给其赋值为METH_NOARGS
- 第四个参数:函数的文档字符串,可以直接给其赋值为NULL
- */
- static PyMethodDef func_methods[] = {
- { "add", (PyCFunction)add, METH_VARARGS, "add" },
- { NULL, NULL, 0, NULL }
- };
-
- //Python初始化模块所需的数据结构
- static struct PyModuleDef func_module = {
- PyModuleDef_HEAD_INIT,
- "func", /* 模块名*/
- NULL, /* 模块文档字符串,通常为NULL */
- -1, /* 模块每个解释器状态的大小,如果模块将状态保存在全局变量中,则为-1 */
- func_methods /* 模块所提供的接口映射函数列表 */
- };
-
- //Python模块的初始化函数
- PyMODINIT_FUNC PyInit_func(void) //该函数的名称为PyInit_模块名
- {
- return PyModule_Create(&func_module); //使用数据结构func_module进行初始化
- }
除了C语言文件外,还需要一个setup.py文件,用于在编译C语文件时使用
- #setup.py
- #通过:sudo apt-get install python3-distutils,可以安装distutils
- from distutils.core import setup, Extension
-
- #name='c_func',用于包名
- #ext_modules,用于指出包内包含的模块列表
- #Extension,用于描述模块名及其对应的C语言文件,还可以通过include_dirs=['aa', 'bb']设置头文件目录,libraries=['cc', 'dd']依赖库的列表
- setup(name='c_func', ext_modules=[Extension('func', sources=['func.c'])])
完成了C语言文件和setup.py后可以通过如下命令进行编译:
编译后,当前目录下会参数一个so文件,比如:
func.cpython-38-x86_64-linux-gnu.so
其中cpython-38-x86_64-linux-gnu为平台的名,可以不用关注
此时,可以被Python使用的C语言模块已经准备好,可以通过如果程序进行使用:
- #fun.py
- import func #导入模块
-
- if __name__ == '__main__':
- result = func.add(1, 9) #调用模块的接口函数add
- print(result)
python3 ./fun.py #运行程序输出:
c call do_add, 1 + 9 = 10
10可见Python程序成功的调用了C语言程序,实现了混合编程