芜湖市临终服务网

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
学习曲线 简单 中等 陡峭 中等 中等
性能 良好 良好 优秀 优秀 优秀
内存安全 取决于实现
开发速度 中等
维护成本 中等 中等
跨平台 优秀 优秀 优秀 优秀 优秀
调试难度 简单 中等 困难 中等 中等

选择建议

快速原型ctypesCFFI

性能关键PyBind11Cython

复杂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在平衡开发效率和运行时性能方面表现最佳。

相关推荐