C++如何为Python编写扩展模块

来源:站长工具作者:冷风头衔:草根站长
导读:本期聚焦于小伙伴创作的《C++如何为Python编写扩展模块》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何为Python编写扩展模块》有用,将其分享出去将是对创作者最好的鼓励。

C++编写Python扩展模块是提升Python程序性能、复用现有C++代码库的常见方案,目前主流实现方式分为传统Python C API和第三方封装库两种,其中pybind11因语法简洁、学习成本低被广泛使用。

C++如何为Python编写扩展模块

两种实现方式对比

在选择实现方案前,首先了解两种主流方式的差异,方便根据项目需求选择:

方案类型优势劣势适用场景
Python C API无需额外依赖,官方原生支持语法繁琐,手动管理引用计数容易出错无第三方库依赖要求的小型模块
pybind11语法接近C++原生,自动管理引用,兼容C++11及以上标准需要引入第三方库复杂业务模块、需要大量C++特性支持的场景

基于pybind11的实现步骤

环境准备

首先安装pybind11库,推荐使用pip安装,同时需要确保本地已安装C++编译环境,Windows系统需要安装Visual Studio,Linux系统需要安装gcc,macOS系统需要安装Xcode命令行工具。

# 安装pybind11
pip install pybind11
# 查看Python头文件路径,后续编译需要
python -c "import sysconfig; print(sysconfig.get_path('include'))"

编写C++扩展代码

下面编写一个简单的扩展模块,实现两个功能:一个加法函数,一个存储数据的简单类。

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;

// 普通函数,计算两个整数之和
int add(int a, int b) {
    return a + b;
}

// 定义一个简单的C++类
class DataProcessor {
private:
    int data;
public:
    DataProcessor(int init_val) : data(init_val) {}

    // 设置数据
    void set_data(int new_val) {
        data = new_val;
    }

    // 获取数据
    int get_data() const {
        return data;
    }

    // 数据翻倍
    int double_data() {
        data *= 2;
        return data;
    }
};

// 模块定义,模块名为my_cpp_module
PYBIND11_MODULE(my_cpp_module, m) {
    m.doc() = "这是一个用C++编写的Python扩展模块"; // 模块文档

    // 注册加法函数
    m.def("add", &add, "计算两个整数的和",
          py::arg("a"), py::arg("b"));

    // 注册DataProcessor类
    py::class_<DataProcessor>(m, "DataProcessor")
        .def(py::init<int>(), "初始化处理器,传入初始值")
        .def("set_data", &DataProcessor::set_data, "设置存储的数据")
        .def("get_data", &DataProcessor::get_data, "获取存储的数据")
        .def("double_data", &DataProcessor::double_data, "将数据翻倍并返回");
}

编译扩展模块

编写好代码后,需要将其编译为Python可识别的动态链接库,Windows下生成.pyd文件,Linux/macOS下生成.so文件。

可以使用pybind11提供的编译工具简化编译流程,创建一个setup.py文件:

from setuptools import setup, Extension
import pybind11

# 定义扩展模块
ext_module = Extension(
    'my_cpp_module',
    sources=['my_cpp_ext.cpp'], # 你的C++源码文件名
    include_dirs=[pybind11.get_include()],
    language='c++'
)

setup(
    name='my_cpp_module',
    version='1.0',
    description='C++编写的Python扩展模块',
    ext_modules=[ext_module]
)

在终端执行以下命令完成编译:

# 编译并安装模块到当前Python环境
python setup.py install

测试扩展模块

编译完成后,就可以在Python中直接导入使用这个模块了:

import my_cpp_module

# 测试加法函数
result = my_cpp_module.add(3, 5)
print(f"3 + 5 = {result}")

# 测试DataProcessor类
processor = my_cpp_module.DataProcessor(10)
print(f"初始数据: {processor.get_data()}")
processor.double_data()
print(f"翻倍后数据: {processor.get_data()}")
processor.set_data(20)
print(f"设置新数据后: {processor.get_data()}")

传统Python C API实现示例

如果不想依赖第三方库,也可以使用Python原生的C API实现扩展,下面是相同功能的实现代码:

#include <Python.h>

// 加法函数实现
static PyObject* py_add(PyObject* self, PyObject* args) {
    int a, b;
    // 解析Python传入的参数
    if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
        return NULL;
    }
    int result = a + b;
    // 将结果转换为Python整数对象返回
    return PyLong_FromLong(result);
}

// 模块方法列表
static PyMethodDef MyCppMethods[] = {
    {"add", py_add, METH_VARARGS, "计算两个整数的和"},
    {NULL, NULL, 0, NULL} // 结束标记
};

// 模块定义
static struct PyModuleDef my_cpp_module = {
    PyModuleDef_HEAD_INIT,
    "my_cpp_module", // 模块名
    "原生C API实现的Python扩展模块", // 模块文档
    -1,
    MyCppMethods
};

// 模块初始化函数
PyMODINIT_FUNC PyInit_my_cpp_module(void) {
    return PyModule_Create(&my_cpp_module);
}

这种方式的编译需要指定Python的头文件路径和库路径,编译命令示例(Linux环境):

gcc -shared -fPIC -I$(python3 -c "import sysconfig; print(sysconfig.get_path('include'))") my_cpp_ext.c -o my_cpp_module.so -lpython3.8

注意事项

  • C++编译标准需要匹配pybind11的要求,建议至少使用C++11标准,编译时添加-std=c++11参数
  • 使用Python C API时一定要注意引用计数管理,避免内存泄漏或者野指针问题
  • 如果扩展中需要使用numpy等库的数据结构,pybind11提供了对应的pybind11/numpy.h头文件支持
  • 不同Python版本的C API存在细微差异,编写原生扩展时需要做好版本兼容处理

C++Python扩展模块pybind11修改时间:2026-06-21 23:48:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。