芜湖市临终服务网

Python调用C函数的5种方式总结大比拼

2026-03-28 19:54:01 浏览次数:0
详细信息

1. ctypes(标准库)

import ctypes
import os

# 加载动态库
lib = ctypes.CDLL('./mylib.so')  # Linux
# lib = ctypes.CDLL('mylib.dll')  # Windows

# 调用C函数
lib.my_function.argtypes = [ctypes.c_int, ctypes.c_float]
lib.my_function.restype = ctypes.c_double
result = lib.my_function(10, 3.14)

特点:

2. CFFI(C Foreign Function Interface)

from cffi import FFI

ffi = FFI()
ffi.cdef("""
    double my_function(int a, float b);
""")

lib = ffi.dlopen('./mylib.so')
result = lib.my_function(10, 3.14)

特点:

3. Python C API(最底层)

// C扩展模块
#include <Python.h>

static PyObject* py_my_function(PyObject* self, PyObject* args) {
    int a;
    float b;
    if (!PyArg_ParseTuple(args, "if", &a, &b))
        return NULL;

    double result = my_function(a, b);
    return PyFloat_FromDouble(result);
}

特点:

4. PyBind11(现代C++绑定)

#include <pybind11/pybind11.h>
#include "my_library.h"

PYBIND11_MODULE(example, m) {
    m.def("my_function", &my_function, 
          "A function that adds two numbers",
          py::arg("a"), py::arg("b"));
}

特点:

5. Cython

# example.pyx
cdef extern from "my_library.h":
    double my_function(int a, float b)

def py_my_function(int a, float b):
    return my_function(a, b)

特点:

综合对比表格

特性 ctypes CFFI Python C API PyBind11 Cython
学习曲线 简单 中等 陡峭 中等 中等
性能 良好 良好 优秀 优秀 优秀
内存安全 低 高 取决于实现 高 高
开发速度 快 快 慢 中等 快
维护成本 低 低 高 中等 中等
跨平台 优秀 优秀 优秀 优秀 优秀
调试难度 简单 中等 困难 中等 中等

选择建议

快速原型 → ctypes或CFFI

性能关键 → PyBind11或Cython

复杂C++项目 → PyBind11

已有Python代码优化 → Cython

底层控制 → Python C API

性能测试示例

import timeit

# 测试不同方式的调用开销
ctypes_time = timeit.timeit('lib.my_func(1, 2.0)', 
                           setup='import ctypes; lib=...')
cffi_time = timeit.timeit('lib.my_func(1, 2.0)',
                         setup='from cffi import FFI; ffi=...')
# 通常:Python C API ≈ PyBind11 < Cython < CFFI < ctypes

最佳实践

从ctypes/CFFI开始,验证功能可行性 使用PyBind11进行生产部署(C++项目) 用Cython包装现有的C库(C项目) 始终添加类型检查和错误处理 提供纯Python回退实现以便调试

选择时考虑团队熟悉度、项目规模和性能需求,通常PyBind11和Cython在平衡开发效率和运行时性能方面表现最佳。

相关推荐