C++和Python混合编程——Python调用C++入门

大纲

  • 背景
  • 代码入门
    • 环境准备
    • 头文件
    • 业务代码
    • 注册
      • BOOST_PYTHON_MODULE
        • 作用
      • boost::python::class_模板类
  • 编译
  • 运行
  • 项目地址

背景

Python语言在大数据、人工智能以及大模型开发中扮演着举足轻重的角色,其影响力不断扩大并深化。

在大数据领域,Python以其简洁易学的语法、高效的计算能力和丰富的库支持,成为处理海量数据的首选工具。它不仅能够帮助开发者进行数据清洗、去重、转换等预处理工作,还具备强大的数据分析能力,能够通过Pandas、NumPy等库实现数据的高效处理和分析。此外,Python在数据可视化方面也有出色的表现,利用Matplotlib、Seaborn等库可以轻松地将复杂的数据以直观、易懂的形式呈现出来,帮助人们更好地理解数据背后的信息。

在人工智能领域,Python同样占据着重要的地位。其灵活性和强大的扩展性使得Python成为实现和优化各种算法和模型的首选语言。从基础的数据挖掘与机器学习,到复杂的深度学习、自然语言处理和计算机视觉,Python都提供了丰富的库和框架支持。例如,Scikit-learn、TensorFlow、Keras等库在机器学习和深度学习领域应用广泛,为研究人员和开发者提供了强大的工具集。Python还支持多种编程语言和平台的集成,如Java、.NET组件或C/C++库,使得在复杂的系统中也可以轻松实现跨语言操作。

在大模型开发中,Python凭借其灵活性和广泛的支持库同样表现出色。大型模型开发通常需要处理大量的数据和复杂的计算任务,Python提供的TensorFlow、PyTorch等深度学习框架提供了丰富的神经网络结构和优化算法,使得开发者可以轻松地构建和训练大型模型。同时,Python社区活跃,不断有新的库和工具被开发出来,为AI研究与应用的发展提供了有力的支持。

Python,作为一门高级、解释型、动态类型的编程语言,以其简洁的语法、丰富的库支持和强大的社区力量,在数据科学、Web开发、自动化脚本等多个领域大放异彩。然而,在追求极致性能、内存管理或需要直接与系统底层交互的场景中,Python可能展现出其局限性。这时,C++作为一门静态类型、编译型语言,以其出色的性能、严格的类型检查以及对底层硬件的直接操作能力,成为了补充Python不足的理想选择。

C++和Python的混合编程可以在以下场景下发挥出优势:

  1. 性能优化
    对于计算密集型或资源敏感型任务,C++因其高效的执行速度和资源管理能力成为首选。然而,这类任务往往需要复杂的逻辑处理,直接使用C++编程可能会增加开发难度和维护成本。通过Python调用C++编写的关键部分,可以在不牺牲性能的前提下,简化上层逻辑的实现。
  2. 快速原型开发
    Python以其简洁的语法和丰富的库支持,非常适合快速开发原型和算法验证。当原型验证成功,需要进一步优化性能以满足生产环境需求时,可以将性能瓶颈部分的Python代码替换为C++实现,或者通过Python调用C++库来加速执行。
  3. 跨语言协作
    在大型项目中,团队成员可能擅长不同的编程语言。Python和C++的混合使用可以充分利用团队中不同成员的技能,促进跨语言协作,提高整体开发效率。
  4. 利用现有资源
    许多遗留系统或第三方库是用C++编写的,这些资源在性能上经过优化,功能丰富。通过Python调用这些C++代码或库,可以方便地将这些资源集成到新的或现有的Python项目中,避免重复造轮子。
  5. 系统级编程需求
    对于需要直接与系统硬件交互、进行低级内存管理或实现特定系统功能的场景,C++的底层控制能力不可或缺。而Python的脚本特性则适合作为这些底层功能的封装和调用接口,提供更高层次的抽象和易用性。

下面我们就来讲解,如果进行C++和Python的混合编程。

代码入门

环境准备

我们要安装boost开发库。这是因为后续我们会使用boost.python库来做混合编程。

udo apt-get install libboost-all-dev

头文件

首先我们需要引入boost.python库的头文件

#include <boost/python.hpp>

业务代码

然后像写普通C++类一样写一个类DemoClass 。

这个类的构造函数接受一个int型形参,这点需要和后续代码进行呼应。

其他逻辑就是简单的设置值和返回值操作。

class DemoClass {
public:DemoClass(int value) : value(value) {std::cout << "Constructor: DemoClass created with value " << value << std::endl;}int getValue() const {std::cout << "getValue: Returning value " << value << std::endl;return value;}void setValue(int newValue) {std::cout << "setValue: Setting value to " << newValue << std::endl;value = newValue;}private:int value;
};

注册

BOOST_PYTHON_MODULE(demo_module) {using namespace boost::python;class_<DemoClass>("CplusplusClass", init<int>()).def("get", &DemoClass::getValue).def("set", &DemoClass::setValue);
}

BOOST_PYTHON_MODULE

BOOST_PYTHON_MODULE 是 Boost.Python 库中的一个宏,用于定义一个 Python 模块。这个宏将 C++ 代码中的类和函数导出到 Python,使得它们可以在 Python 中被调用和使用。

作用
  • 定义模块:指定模块的名称,这个名称将用于在 Python 中导入模块。
  • 导出类和函数:在模块定义中,可以使用 Boost.Python 提供的各种函数将 C++ 类和函数导出到 Python。

boost::python::class_模板类

我们将需要导出的类DemoClass作为boost::python::class_模板类,构造出一个对象。初始化时,第一个参数"CplusplusClass"是我们在Python中使用的类名(对应于C++中的DemoClass);第二个参数和DemoClass的构造函数呼应,即使用一个int型变量进行对象构造。

def方法将C++中的方法映射到Python类中的方法名。如上例,Python中CplusplusClass::get映射到DemoClass::getValue;CplusplusClass::set映射到DemoClass::setValue。

编译

我们使用Cmake来编译这个项目。它将产出一个动态链接库。

需要注意的是最终我们生成的动态链接库名称要和代码中BOOST_PYTHON_MODULE中定义的模块名一致。本例中模块名是demo_module

cmake_minimum_required(VERSION 3.12)# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -O3")# 查找 Boost 库
find_package(Boost REQUIRED COMPONENTS python)# 查找 Python 库
find_package(PythonLibs REQUIRED)# 包含 Boost 和 Python 头文件
include_directories(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})# 添加动态链接库文件
add_library(demo_module SHARED main.cpp)# 链接 Boost 和 Python 库
target_link_libraries(demo_module ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})# 设置输出目录
set_target_properties(demo_module PROPERTIES PREFIX "" SUFFIX ".so")

运行

我们需要让python进程可以找到上述编译的动态链接库,则可以在工程目录下执行下面命令

source python_env.sh

python_env.sh的内容如下:

#!/bin/bash# 获取当前目录
CURRENT_DIR=$(pwd)# 设置构建目录路径
BUILD_DIR="$CURRENT_DIR/build"# 将构建目录添加到 PYTHONPATH
export PYTHONPATH=$PYTHONPATH:$BUILD_DIR# 输出当前的 PYTHONPATH
echo "PYTHONPATH is set to: $PYTHONPATH"

这样在当前终端中启动的python就可以找到库了。

在这里插入图片描述

项目地址

https://github.com/f304646673/cpulsplus/tree/master/boost_python/p_call_c

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/415898.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unittest | 使用unittest模块来测试logging日志模块功能

我们在这篇文章实现了在项目工程中编写一个logging模块&#xff0c;但是我们如何确定我们编写的模块功能的是否正常? 你可能想到将全部代码写完后运行测试&#xff0c;但这是一个非常不好的习惯。❌ 最好的方式&#xff0c;是每写出来一个功能或者方法就对它进行测试&#x…

Java设计模式之装饰器模式详细讲解和案例示范

1. 引言 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许向现有对象添加新的功能&#xff0c;而无需修改其结构。这种模式通过使用组合而非继承来扩展对象的行为&#xff0c;在许多实际应用中极为常见。本文将详细介绍装饰器模式…

使用 docker 部署 kvm 图形化管理工具 WebVirtMgr

文章目录 [toc]前提条件镜像构建启动 webvirtmgr创建其他 superuser配置 nginx 反向代理和域名访问绑定 kvm 宿主机local sockettcp 连接 虚拟机创建创建快照虚拟机克隆删除虚拟机 kvm 官方提供了以下这些图形化管理&#xff0c;license 这块也提示了是商业版&#xff08;Comme…

Android实习面经整理第一篇

蔚来Android实习面经 一面(2024/3/11 35min) 自我介绍聊我的本专业说一说MVP架构,MVVM架构 MVP:V层持有P层,用户点击View,把数据发给P层,P层持有M层,然后P层把V层的数据发给M层获取其他数据,最后M层获取完数据后把数据还给P层,更新V层。P层也有V层的引用。MVVM:V层…

Qt 去掉QDialog对话框的问号

QT 对话框的问号是什么&#xff1f; QDialog默认的window flag中包含了Qt::WindowContextHelpButtonHint,这个flag意思是在窗口上提供“上下文帮助”按钮 使用方式/调用方式 void QWidget::setWhatsThis(const QString &)比如&#xff1a; ui->lineEdit_1->setWh…

【pycharm-乱码】简单记录一下都有哪些涉及编码

控制台 路径&#xff1a;setting-》general-》console setting-》editor-》file encodings 路径&#xff1a;setting-》editor->file and code templates #!/user/bin/env python3 # -*- coding: utf-8 -*-setting->tools->ssh terminal

Conda在线/离线迁移虚拟环境

conda简单使用 1.创建环境&#xff1a; conda create -n myenv python3.82.激活环境 conda activate myenv3.退出环境 conda deactivate4.安装包 pip install xxx5.列出所有环境 conda env list conda info --envs6.删除环境 conda remove -n myenv --all离线迁移conda …

【JavaWeb】JDBCDruidTomcat入门使用

本章使用技术版本&#xff1a; Tomcatv10.1.25 关于javaweb相关的其他技术&#xff0c;比如tomcat和maven&#xff0c;在我的主页记录了笔记&#xff0c;ajax我用的是本地笔记以后再考虑上传&#xff0c;前端三板斧我用的菜鸟教程文档 JDBC 初识 JDBC概念 JDBC 就是使用Jav…

三、建造者模式

构造者模式&#xff08;Builder Pattern&#xff09;使用简单的对象一步一步构建成一个复杂的对象。这种设计模式属于创建者模式&#xff0c;它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。例如&#xff0c;计算…

LVDS与SerDes到底是什么关系?

随着智能座舱和智能驾驶功能的应用&#xff0c;汽车中的摄像头和液晶屏越来越多&#xff0c;多种图像显示和多屏互动也成为增强汽车智能化和用户体验的重点内容。 这些图像显示功能需要在不同的控制器之间或者控制器与远端的液晶屏或摄像头之间进行数据传输。 比如中控与仪表之…

AndroidLogger 适配好了,但没法上架

看到有网友还在用之前的 AndroidLogger 版本&#xff0c;让我感动再次花了 2个月适配新的Notepad&#xff0c;总算搞完了&#xff0c;但是Notepad作者反了&#xff0c;我没法上架啊。 演示视频地址&#xff1a; Notepad安卓日志插件&#xff0c;支持文件管理和截屏&#xff0c…

FreeRTOS学习笔记—②RTOS的认识(持续更新中)

由于正在学习韦东山大佬的RTOS课程&#xff0c;结合了网上的一些资料&#xff0c;整理记录了下自己的感悟&#xff0c;用于以后自己的回顾。如有不对的地方请各位大佬纠正。 课程链接&#xff1a;https://www.bilibili.com/video/BV1844y1g7ud/?spm_id_from333.337.search-car…

Elasticsearch 向量数据库本地部署 及操作方法

elasticsearch是个分布式向量数据库&#xff0c;支持多种查找模式。此外还拥有 Metadata、Filtering、Hybrid Search、Delete、Store Documents、Async等能力。本文仅是记录本地测试途中遇到的问题。 一&#xff0c;环境部署 下载软件 首先去官网&#xff0c;选择适合平台下…

GoF 代理模式

代理模式的理解 代理模式&#xff0c;就是自己做不了&#xff0c;需要别人来代理&#xff0c;代替自己来完成。最终这个行为还是要发生&#xff0c;只不过不是由自己来完成&#xff0c;而是由别人代理完成&#xff0c;只是对于客户其他人来说感受不到 代理模式的作用&#xf…

MySQL复习3

视图 视图&#xff08;view&#xff09;是一种虚拟存在的表&#xff0c;是一个逻辑表&#xff0c;本省没有数据&#xff0c;内容由查询定义。 基表&#xff1a;用来创建视图的表叫做基表 通过视图&#xff0c;我们可以查看基表的部分数据。视图数据来自定义视图的查询中使用…

RISC-V (八)定时器中断

​​​​​​​riscv中断的分类 Core local INTerrupt: CLINT CLINT编程接口-寄存器 mtime寄存器&#xff0c;由中断触发的时钟&#xff0c;按照固定频率计数。

【基础算法总结】BFS_多源最短路问题

目录 1. 算法介绍2. 算法原理和代码实现542.01矩阵1020.飞地的数量1765.地图中的最高点1162.地图分析 3. 算法总结 1. 算法介绍 所谓多源&#xff0c;就是有多个起点。对应上一篇文章【BFS_最短路问题】的单源问题。这篇文章介绍用bfs解决边权为1(或边权相等)的多源最短路问题…

监控平台之rollup打包

设计思路 1.根据模块&#xff0c;通过index.js去调用执行调用 2.WebEyeSDK.js暴露方法&#xff0c;同时定义init方法&#xff0c;去初始化config里的上报参数 3.rollup/build里入口文件为WebEyeSDK.js进行打包 4.打包编译用babel&#xff0c;同时安装babel/preset-env智能预…

网络安全服务基础Windows--第12节-域与活动目录

工作组 在Windows环境中配置⼯作组相对简单&#xff0c;适合⼩型⽹络环境&#xff0c;如家庭或⼩型办公室⽹络。⼯作组通过简单的⽹络共享和本地管理来实现资源共享&#xff0c;⽽不依赖于中央控制的服务器。 ● 定义&#xff1a;⼯作组是⼀种对等⽹络模型&#xff0c;在这种…

【鸿蒙开发从0到1 day05】

一. 清除浮动 1.当外面的大盒子,仅仅只设置了宽度,里面的子盒子为了行排序, 设置了浮动,以至于小盒子脱标,大盒子的高度为0,这个时候就会导致大盒子下面的盒子会跑上去 解决办法方法一:给父盒子添加overflow:hidden,这个就是如果子盒子有溢出,,溢出部分会隐藏方法二:在子盒子的…