简单介绍:

一、是什么?

简单说,就是让 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 模块调用它,就像在命令行里运行程序一样。

步骤举例

  1. 写一个简单的 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;
    }
    
  2. 编译成可执行文件:
    • Windows(用 MinGW):gcc add.c -o add.exe
    • Linux/Mac:gcc add.c -o add
  3. 用 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 库一样使用。

步骤举例

  1. 写一个 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);
    }
    
  2. 编译成 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 版本和系统而异)。
  3. 在 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 风格的代码,又想提升速度的场景。

步骤举例

  1. 写一个 Cython 文件(myadd.pyx),语法类似 Python,但可以指定变量类型(提升速度):
    # 定义一个加法函数,指定参数为 int 类型
    def add(int a, int b):
        return a + b
    
  2. 写 setup.py 编译:
    from setuptools import setup
    from Cython.Build import cythonize
    
    setup(
        ext_modules=cythonize("myadd.pyx")  # 直接编译 .pyx 文件
    )
    
  3. 编译:python setup.py build_ext --inplace,生成扩展模块。
  4. 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。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐