程序代码篇---Python 程序和 C/C++ 程序合作
简单介绍:
一、是什么?
简单说,就是让 Python 程序和 C/C++ 程序 “合作干活”。比如,Python 负责处理灵活的逻辑(像用户交互、数据清洗),C/C++ 负责处理需要高性能的部分(像复杂计算、底层操作),两者通过某种方式调用对方的功能。
二、为什么要结合?
因为 Python 和 C/C++ 各有优缺点,结合起来能扬长避短:
- Python 的优点:语法简单、开发快、库多(比如处理数据的 Pandas、画图的 Matplotlib),但缺点是速度慢(解释型语言,执行效率低)、对底层硬件控制弱。
- C/C++ 的优点:速度极快(编译型语言,直接操作内存)、能调用硬件接口(比如驱动开发),但缺点是语法复杂、开发慢、库不如 Python 丰富。
举个例子:如果写一个 “实时视频特效” 程序,用 Python 调用摄像头、处理用户操作很方便,但视频帧的复杂计算(比如美颜算法)用 Python 会卡顿,这时候让 C++ 来算,就能既灵活又高效。
三、怎样结合?(3 种常用方法,从简单到复杂)
方法 1:直接调用 C/C++ 编译的可执行文件(最简单)
思路:把 C/C++ 代码编译成独立的程序(比如 Windows 上的 .exe,Linux 上的可执行文件),然后用 Python 的 os 或 subprocess 模块调用它,就像在命令行里运行程序一样。
步骤举例:
- 写一个简单的 C 程序(
add.c),功能是计算两个数的和,并输出结果:#include <stdio.h> int main(int argc, char *argv[]) { int a = atoi(argv[1]); // 接收第一个参数 int b = atoi(argv[2]); // 接收第二个参数 printf("%d", a + b); // 输出结果 return 0; } - 编译成可执行文件:
- Windows(用 MinGW):
gcc add.c -o add.exe - Linux/Mac:
gcc add.c -o add
- Windows(用 MinGW):
- 用 Python 调用它(传参数、拿结果):
import subprocess # 调用 add 程序,传入 3 和 5 result = subprocess.check_output(["./add", "3", "5"], text=True) print("结果:", result) # 输出:结果:8
优点:简单,不需要懂复杂的接口;缺点:只能通过 “命令行参数” 和 “输出文本” 传递数据,效率低,不适合频繁调用。
方法 2:用 C 扩展(让 Python 直接调用 C 函数,较常用)
思路:把 C 代码写成 Python 能识别的 “扩展模块”,编译后变成 .pyd(Windows)或 .so(Linux)文件,然后像导入普通 Python 库一样使用。
步骤举例:
- 写一个 C 扩展(
myadd.c),定义一个 Python 可调用的函数add:#include <Python.h> // Python 扩展必须包含的头文件 // 定义 C 函数:计算 a + b static PyObject* myadd_add(PyObject* self, PyObject* args) { int a, b; // 解析 Python 传入的参数(这里是两个整数) if (!PyArg_ParseTuple(args, "ii", &a, &b)) { return NULL; // 解析失败返回空 } // 返回结果给 Python(用 Py_BuildValue 包装成 Python 类型) return Py_BuildValue("i", a + b); } // 定义函数列表:告诉 Python 这个模块有哪些函数 static PyMethodDef MyAddMethods[] = { {"add", myadd_add, METH_VARARGS, "计算两个数的和"}, // "add" 是 Python 调用时的名字 {NULL, NULL, 0, NULL} // 结束标志 }; // 定义模块信息 static struct PyModuleDef myaddmodule = { PyModuleDef_HEAD_INIT, "myadd", // 模块名(Python 中 import myadd) "一个简单的加法模块", // 模块说明 -1, MyAddMethods }; // 模块初始化函数(必须叫 PyInit_模块名) PyMODINIT_FUNC PyInit_myadd(void) { return PyModule_Create(&myaddmodule); } - 编译成 Python 扩展模块:写一个
setup.py脚本(用 Python 的setuptools工具):
然后执行编译:from setuptools import setup, Extension # 定义扩展模块:名字是 myadd,源文件是 myadd.c module = Extension('myadd', sources=['myadd.c']) setup( name='myadd', version='1.0', description='一个 C 扩展示例', ext_modules=[module] )python setup.py build_ext --inplace编译后会生成myadd.cp39-win_amd64.pyd(文件名因 Python 版本和系统而异)。 - 在 Python 中使用:
import myadd print(myadd.add(3, 5)) # 直接调用 C 函数,输出:8
优点:调用效率高(几乎和纯 C 一样),可以直接传递 Python 数据类型(整数、字符串等);缺点:需要学 Python 扩展的 C API,语法较繁琐,只支持 C(C++ 需额外处理)。
方法 3:用 Cython(简化 C 扩展,推荐)
Cython 是一个 “中间语言”,语法接近 Python,但能编译成 C 代码,再生成 Python 扩展。适合既想写 Python 风格的代码,又想提升速度的场景。
步骤举例:
- 写一个 Cython 文件(
myadd.pyx),语法类似 Python,但可以指定变量类型(提升速度):# 定义一个加法函数,指定参数为 int 类型 def add(int a, int b): return a + b - 写
setup.py编译:from setuptools import setup from Cython.Build import cythonize setup( ext_modules=cythonize("myadd.pyx") # 直接编译 .pyx 文件 ) - 编译:
python setup.py build_ext --inplace,生成扩展模块。 - Python 中调用(和普通库一样):
import myadd print(myadd.add(3, 5)) # 输出:8
优点:比直接写 C 扩展简单,支持 C++(加参数即可),适合优化 Python 中的热点代码;缺点:需要额外安装 Cython(pip install cython),复杂逻辑仍需懂 C 语法。
四、总结
- 简单场景(偶尔调用、数据量小):用方法 1(调用可执行文件);
- 高性能需求(频繁调用、数据量大):用方法 2(C 扩展)或方法 3(Cython),其中 Cython 更易上手;
- 核心目的:让 Python 负责 “灵活”,C/C++ 负责 “快速”,1+1>2。
更多推荐
所有评论(0)