如何在 C/C++ 中包装 Python 对象?2025 年 3 月 25 日 | 阅读 6 分钟 Python 是一种解释型、面向对象的语言,开箱即用地提供了动态类型、反射和高级数据类型等强大功能。Python 丰富的对象模型是其关键优势之一,它能够实现快速应用程序开发和清晰、可读的代码。 然而,对于应用程序中 CPU 或内存密集型的部分,与 C/C++ 等静态编译型语言相比,Python 的动态特性会带来性能开销。因此,将 Python 的易用性用于高级逻辑,并结合 C/C++ 的速度和效率用于性能关键型例程,具有明显的优势。 一种有效的技术可以获得“两全其美”的效果,那就是封装 Python 对象,使其可以直接从 C 或 C++ 代码中使用。这使得可以将关键的应用程序逻辑、类和数据结构保留在高生产力的 Python 中,同时又能从低级的 C/C++ 代码中访问它们。无缝的互操作性开启了许多有趣的可能。 本文探讨了封装 Python 对象以便在 C/C++ 中使用的不同方法。我们将涵盖以下概念:
假设您同时具备 Python 和 C/C++ 的一些经验。读完本文后,您应该会理解在您自己的高性能 C/C++ 应用程序中利用 Python 面向对象特性的技术。让我们开始吧! 目标是提供背景信息,说明为什么在许多领域中从 C/C++ 访问 Python 对象非常有用,并介绍文章其余部分涵盖的核心主题。如果您希望我对引言进行修改或扩展,请告诉我。 访问 Python 对象的步骤1. 直接访问 Python C API
2. 使用 Boost.Python 或 pybind11 等辅助库
3. 从 C++ 创建和操作 Python 对象
4. 从 C++ 调用 Python 对象方法
5. 正确管理引用和内存
因此,总而言之,通过 Python C API 集成 C++/Python 是可行的,但更底层且容易出错。pybind11 或 Boost 等辅助库。大大简化了从 C++ 代码包装和与 Python 对象交互的过程。它们处理繁琐的底层内存管理,同时暴露简单、原生的接口。 代码实现1. 直接访问 Python C API 输出 [] 说明
2. 使用 pybind11 辅助库 输出 [] 3. 从 C 创建和操作 Python 对象 输出 {'key': 10, 'other': 'value'} 4. 从 C++ 调用 Python 对象方法 输出 10 5. 正确管理内存 输出 Ref count: 1 Python C API在 C/C++ 中封装 Python 对象的基础是 Python/C API。Python 解释器公开的标准函数和接口集允许其他代码与 Python 对象进行交互。Python 本身就是建立在它之上的。 Python/C API 提供的一些关键功能包括:
因此,通过利用几十种可用的 API 调用,您可以从纯 C/C++ 代码中完全控制和操作 Python 对象和环境。 基本对象包装从 C++ 包装基本 Python 对象(如整数)的步骤是:
例如 1. 包含头文件 2. 创建整数 3. 操作对象 4. 属性访问 5. 引用处理 类包装要包装自定义 Python 类,您需要:
这需要更多的努力,但提供了从 C++ 完全控制 Python 类的能力。 通过辅助库简化手动处理 Python C API 可能很麻烦。因此,像 Boost.Python 和 pybind11 这样的库通过高级包装器和自动引用计数极大地简化了这一过程。 例如,使用 pybind11 这些库使得在 C++ 中包装 Python 对象变得简洁且具有原生感。 关于生命周期管理、异常处理和高级包装技术还有更多细节。但这个概述涵盖了通过 Python C API(直接或通过辅助库)在 C/C++ 代码中公开 Python 对象的主要步骤。 结论当您将 Python 的功能与 C/C++ 的性能相结合时,您就可以为需要生产力和速度的应用程序开辟新的可能性。通过使 C/C++ 可以访问 Python 对象,代码开发人员可以利用每种语言最适合其优势的地方。 Python/C API 是此过程的核心,它提供了一系列函数和接口,可用于从 C/C++ 代码与 Python 解释器和对象模型进行交互。使用此底层 API,C/C++ 程序可以轻松地创建 Python 对象,调用其方法,访问属性,并高效地管理内存。然而,手动使用 C API 包装 Python 涉及大量样板代码和引用计数处理。 Boost.Python 和 pybind11 等库提供了 Python API 的高级包装器,以简化此集成过程。只需几行 C++ 代码,这些库就可以自动生成绑定,以供 C++ 使用 Python 类、模块和对象。辅助库在级别上负责引用计数、异常处理和其他复杂细节。 这会在将 Python 集成到 C++ 时提供一种体验。当然,存在挑战,例如处理跨语言的对象管理以及频繁在 Python 和编译的 C/C++ 代码之间切换的潜在性能影响。与任何涉及语言的解决方案一样,重要的是要设计它以充分利用每种语言的优势。Python 对象可能不应该被包装到每个细微的例程中,但只专注于核心性能关键部分可以产生可观的收益。 将最新的 C++ 标准与 Python 成熟的对象模型相结合,可以在适当利用时成为强大的组合。C++ 开发人员可以利用 Python 丰富的 数据科学库和框架。Python 开发人员可以注入高性能内核,而不会牺牲编码生产力。无论用例如何,在 C/C++ 中包装 Python 对象都为在现代软件开发中统一简单性和速度这一挑战性任务提供了一个可行的解决方案。 |
简介多态内存资源 (PMR) 是 C++17 标准库的一部分,旨在作为灵活的自由存储。因此,PMR 框架添加了一种以实践为中心的方法来通用处理自定义内存分配机制,从而允许提供...
阅读 10 分钟
简介 在 C++ 开发中,可以通过多种方式实现性能的资源优化。这对于旨在提供高性能的应用程序尤其重要。然而,有一个特定领域可以得到改进:编译的链接部分,...
11 分钟阅读
在 C++23 中,ranges 库将包含一个名为 zip 的算法,该算法接受两个或多个输入范围(例如,列表或向量)。在接收两个(或一般情况下的任意数量)范围后,zip_view 会生成一个元组的单个范围,其中每个元组包含一个元素……
阅读 4 分钟
简介:有些电影有限制,例如年龄限制,甚至限制电影院的座位数。那么,基于这些标准,我们能否确定有多少人可能观看电影?我们将讨论这个问题...
11 分钟阅读
在本文中,我们将讨论 SFINAE 和 Concepts 之间的区别。在讨论它们的区别之前,我们必须了解 SFINAE 和 Concepts 及其功能。什么是 SFINAE?SFINAE 是一种 C++ 机制,它根据特定类型替换是否….
5 分钟阅读
引言:竞技场分配,也称为基于区域的内存管理,是一种内存管理技术,其中内存从预先分配的“竞技场”或“池”中批量分配,然后进行细分以满足更小的分配请求。关键思想是分配一个大的连续内存块...
阅读 13 分钟
简介:Cooley-Tukey 快速傅立叶变换 (FFT) 算法是计算复数序列或数组离散傅立叶变换 (DFT) 的一种广泛使用且高效的方法。它由 J.W. Cooley 和 John Tukey 于 1965 年引入,此后已成为基础......
14 分钟阅读
在本文中,我们将讨论带实现。简介:纸牌翻转游戏是一种简单但有趣的游戏,玩家将牌面朝下放在网格中进行翻转。此游戏的目标是通过一次翻转两张牌来找到匹配的对...
阅读 6 分钟
在本文中,我们将讨论 C++ 中联合数据类型和变体的区别。在深入探讨区别之前,让我们先了解每个术语及其优缺点。什么是联合?在 C++ 中,联合是一个非常特殊的构造,它使得多个...
5 分钟阅读
在C++编程语言中,二项式随机变量表示一系列独立试验的结果,每项试验有两个可能的结果:成功或失败。这些试验遵循二项分布。参数“n”表示试验次数,“p”表示概率……
阅读 4 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India