在C/C++程序中实现Python绑定有多种技术路线,选择合适的方法取决于项目需求、性能要求和开发效率。以下是常见的几种方案,按易用性排序:
1. PyBind11(推荐首选)
特点:现代C++库,语法简洁,无需额外工具链。
适用场景:C++项目,需要高性能和易用性。
步骤:
#include <pybind11/pybind11.h>int add(int a, int b) { return a + b; }PYBIND11_MODULE(example, m) {m.def("add", &add, "A function that adds two numbers");
}
优点:
- 自动类型转换(支持STL容器、NumPy等)。
- 直接绑定C++类到Python。
- 头文件仅依赖,编译简单。
安装:pip install pybind11
2. Cython
特点:混合Python/C语法,需编写.pyx
文件并编译。
适用场景:需要精细控制C/C++与Python交互。
示例(example.pyx
):
cdef extern from "example.h":int add(int a, int b)def py_add(a, b):return add(a, b)
编译:通过setup.py
调用Cython编译:
from setuptools import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("example.pyx"))
优点:
- 性能接近原生C。
- 支持逐步优化Python代码。
3. ctypes(Python内置)
特点:无需编译,直接调用动态库(.dll
/.so
)。
适用场景:快速测试已有C库。
示例:
from ctypes import CDLL
lib = CDLL("./example.so")
result = lib.add(2, 3)
注意:
- 需手动处理类型转换(如
c_int
)。 - 不支持C++类(需用C接口封装)。
4. SWIG(传统工具)
特点:自动生成多语言绑定(包括Python),但配置复杂。
适用场景:需要支持多种目标语言的老项目。
示例(example.i
):
%module example
%{
extern int add(int a, int b);
%}
extern int add(int a, int b);
生成命令:swig -python example.i
→ 编译生成模块。
5. 手动Python C API(不推荐)
特点:直接使用Python的C API,灵活性高但易出错。
示例:
#include <Python.h>
static PyObject* py_add(PyObject* self, PyObject* args) {int a, b;if (!PyArg_ParseTuple(args, "ii", &a, &b)) return NULL;return PyLong_FromLong(add(a, b));
}
static PyMethodDef methods[] = {{"add", py_add, METH_VARARGS, "Add two numbers"},{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC PyInit_example(void) {return PyModule_Create(&PyModuleDef_Base);
}
缺点:代码冗长,需处理引用计数等细节。
技术路线对比
方案 | 易用性 | 性能 | 支持C++类 | 依赖项 |
---|---|---|---|---|
PyBind11 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 是 | 仅头文件 |
Cython | ⭐⭐⭐ | ⭐⭐⭐⭐ | 部分 | 需Cython编译 |
ctypes | ⭐⭐ | ⭐⭐ | 否 | 无 |
SWIG | ⭐⭐ | ⭐⭐⭐ | 是 | SWIG工具链 |
Python C API | ⭐ | ⭐⭐⭐⭐ | 是 | 无 |
推荐选择
- 快速绑定C++库:用 PyBind11(语法直观,功能全面)。
- 混合Python/C优化:用 Cython(适合科学计算)。
- 快速调用已有C库:用 ctypes(无需编译)。
- 历史项目迁移:考虑 SWIG。
PyBind11通常是现代C++项目的最佳平衡点,而Cython适合需要深度集成的场景。