混合编程—C++程序中python脚本的嵌入方法(理论部分)

news2024/11/25 16:45:11

一、C++与Python高级编程语言简概

(一)C++

        C++是一种被广泛使用的计算机程序设计语言。它是一种通用程序设计语言,支持多重编程范式,例如过程化程序设计(Procedural programming)、面向对象程序设计(object-oriented programming)泛型程序设计(generic programming)和函数式程序设计(Functional programming)等。作为广泛被使用的工业语言,C++存在多个流行的成熟实现:GCC、基于LLVM的Clang以及Visual C++等。这些实现同时也是成熟的C语言实现,但对C语言的支持程度不一。大多数流行的实现包含了编译器和C++部分标准库的实现。编译器直接提供核心语言规则的实现,而库提供ISO C++标准库的实现[4]。

         基于C++的面向对象程序设计的基本思想及主要特点为:抽象封装继承多态。C++程序的开发通常要经过编辑编译链接运行调试。其中,链接是将多个目标文件以及所需的库文件链接成最终的可执行文件(executable file,exe)的过程,包括合并段、调整段偏移、汇总所有符号以及完成所有符号的重定位/*6*/。具体流程如下所示:

图源:C++语言程序设计 / 郑莉,董渊编著.—5版.—北京:清华大学出版社

C++的适用时机/*4*//*1*/:

        Ⅰ C++适合构造程序中需求稳定的部分,需求变化较大的部分可使用脚本语言;

        Ⅱ 程序需尽量发挥硬件的最高性能,且性能瓶颈在于CPU和内存;

        Ⅲ 程序需频繁地与操作系统或硬件沟通;

        Ⅳ 程序必须使用C++框架/库,如大部分游戏引擎(如Unreal/Source)及中间件(如Havok/FMOD),虽然有些C++库提供其他语言的绑定,但通常原生的API性能最好、最新;

        Ⅴ 项目中某个目标平台只提供C++编译器的支持。         

        按应用领域来说,C++适用于开发服务器软件、桌面应用、游戏、实时系统、高性能计算、嵌入式系统等。

C++性能优于其他语言的原因/*4*/:

        Ⅰ C/C++直接以静态形式把源程序编译为目标平台的机器码;

        Ⅱ 一般而言,C/C++程序在编译及链接时可进行的优化最丰富,启动时的速度最快,运行时的额外内存开销最少,而C/C++相对于动态脚本语言(如Python)减少了运行时的动态类型检测;

        Ⅲ C/C++的运行行为是确定的,且不会有额外行为,也不会有如垃圾收集/*12*/而造成的不确定性延迟,再者,C/C++的数据结构在内存中的布局也是确定的;

        Ⅳ C++的一些功能会使程序性能优于C,其中以内联和模板最为突出。再者,C/C++能直接映射机器码,之间没有另一层中间语言,因此可以做底层优化。

        总而言之,C++许多的性能优点也会带来部分代价,如较长的编译/链接时间、容易出错等导致开发时间和成本增加。

(二)Python

        Python,是一种广泛使用的解释型、高级和通用的编程语言(脚本语言)。Python支持多种编程范型,包括结构化、过程式、反射式、面向对象和函数式编程。它拥有动态类型系统和垃圾回收(引用计数和环检测相结合)功能,能够自动管理内存使用,并且其本身拥有一个巨大而广泛的标准库以及大量的第三方库。Python的设计哲学,强调代码的可读性和简洁的语法,尤其是使用空格缩进来划分代码块。相比于C/C++,Python能让开发者使用更少的代码表达想法[5]。

Python的主要特点/*11*/:

        Ⅰ 跨平台:Python支持Windows、Linux和MAC os等主流操作系统;

        Ⅱ 可移植:代码通常不需要多少改动就能移植到别的平台上使用;

        Ⅲ 可扩展:Python语言本身由C语言编写而成的,既可以在Python中嵌入C语言以提高代码的运行速度和效率,也可以使用C语言重写Python的任何模块;

        Ⅳ 交互式:Python提供很好的人机交互界面,如IDLE和IPython。可以从终端输入执行代码并获得结果,互动的测试和调试代码片段;

        Ⅴ 解释型:Python语言在执行过程中由解释器逐行分析翻译,逐行运行并输出结果;

        Ⅵ 面向对象:Python语言具备所有面向对象特性和功能,支持基于类的程序开发;

        Ⅶ 动态语言:在运行时可以改变其结构。例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其它结构上的变化。

        值得注意的是,Python遵循GPL开源协议,Python编写的源代码通常是不加密的,即发布Python程序,实际上就是发布源代码。对于代码封闭而言,编译型语言(如C++,非ISO)只需发布可执行文件即可,而解释型语言(如Python)则必须发布源码,但是为了增加反编译的门槛和难度,可以使用类似py2exe工具将python源码转换成一个类似于exe的可执行文件形式。

Python的常见应用方向/*11*/:

        常规软件开发、科学计算、自动化运维、云计算、WEB开发、网络爬虫、数据分析、人工智能。

二、基础概念        

        回调函数/*8*//*9*/:在计算机程序设计中,回调函数,简称回调(Callback),是指通过参数将函数传递到其他代码的,某一块可执行代码的引用。回调的形式因程序设计语言有差别,如C++通过将函数指针作为参数传递给其他函数。使用回调的例子有QT中信号槽机制等。

        封装:封装是面向对象方法的一个重要原则,就是把对象的属性和服务结合成一个独立的系统单位(降低耦合),并尽可能隐蔽对象的内部细节。对于“信息隐蔽”,我们可以封装成类,只保留有限的对外接口使之与外部发生联系,从而对外形成一个边界,尽可能屏蔽对象的内部细节。

        脚本程序(Script):使用脚本语言所写的程序。脚本语言是为了缩短传统的“编写、编译、链接、运行”过程而创建的计算机编程语言。早期的脚本语言经常被称为批处理语言或作业控制语言。大多数脚本语言的共性是:良好的快速开发,有效率的执行、解释而非编译执行、和其它语言编写的程序组件之间通信功能强大,但是脚本缺少优化程序以提速或者降低内存的伸缩性。脚本通常以文本(如ASCII)保存,只在被调用时进行解释。

        extern(c++关键字)/*10*/:

        ①修饰全局变量:在声明全局变量的时候使用extern修饰变量,表明该变量定义于其他翻译单元。②修饰全局常量:表明该全局常量拥有外部链接(可以被其他翻译单元发现),否则全局常量默认是只有内部链接,即不可被其他翻译单元发现。③修饰局部变量:表明该局部变量在其他翻译单元中被定义,需要在链接的时候去解析。④修饰一个字符串:形如extern “C” 之类的用法表明后接的代码块(或者后接的声明)使用C语言调用惯例。⑤修饰一个模板:表明该模板已经在其他翻译单元实例化,不需要在这里实例化。

        (注:ISO C和ISO C++从未明确要求源程序被编译,而仅要求翻译,因此C和C++并不是所谓的完全编译型语言。技术上,实现C和C++程序的单位是翻译单元(translation unit),但是C/C++在传统上多以编译器实现[4]。)

/**/ 程序开发基本术语[6]

        源程序:用源语言编写的、有待翻译的程序。源语言可以是汇编语言,也可以是高级程序设计语言,用它们写出的程序都是源程序;

        目标程序:是源程序通过翻译加工以后所生成的程序。目标程序可以用机器语言表示,也可以用汇编语言或其它中间语言表示;

        翻译程序:是指用来把源程序翻译为目标程序的程序。对于翻译程序来说,源程序是它的输入,而目标程序则是其输出。翻译程序分为汇编程序编译程序以及解释程序三种类型,①汇编程序的任务是把用汇编语言写成的源程序翻译成机器语言形式的目标程序;②编译程序是指高级程序设计语言所写的源程序经翻译程序一次性加工生成目标程序(机器码)的过程;③解释程序同样是将高级语言源程序翻译为机器指令的过程。但不同于编译程序的是,它是边翻译边执行的,即输入一句,翻译一句,执行一句,直至将整个源程序翻译并执行完毕。

        编译型语言与解释型语言的区别/*3*/:        

        编译型语言(如C++等,非ISO),其需要针对不同操作系统进行编译以生成相应的底层机器码、若修改源文件则需要重新编译再执行。优点为运行速度快,缺点为繁琐、调试额外耗时和跨平台性较差;解释型语言(如Python等),其基于解释器动态将源代码边解释为机器码,边执行机器命令。优点为跨平台性好、调试较为迅速,缺点为依赖解释器、运行效率较低。

三、混合编程(C++/python)基本知识与封装规范[1][2]

(一)Python扩展(Extending Python)

        目的:附加C函数库来扩展Python的功能。

        应用程序主程序:Python解释器

        流程:首先,将数据值从Python类型转换为C类型。然后,使用转换后的值对C例程执行函数调用。最后,将调用返回的结果数据值从C类型转换为Python类型。

(二)Python嵌入(Embedding Python)

        目的:嵌入Python丰富C/C++应用程序,通常嵌入功能利用Python编写更为简单、逻辑清晰且独特可定制。

        应用程序主程序:C++编译器(需要的时候动态调用Python解释器)

        流程:首先,将数据值从C类型转换为Python类型。然后,使用转换后的值对Python接口例程执行函数调用。最后,将调用返回的结果数据值从Python类型转换为C类型。

(三)C++和Python混合编程的优势与使用Python C API的注意事项[12]

        优势

        Ⅰ 主体系统使用C++实现,保持系统的高效;

        Ⅱ 控制部分使用Python,增加开发效率,Python的内存垃圾回收、丰富的类库都使C++开发者获益匪浅;

        Ⅲ Python脚本可以运行期重载,可以实现控制部分不停机热更新。

        使用Python C API的注意事项

        Ⅰ Python主要使用引用计数管理内存,调用Python C API时对于返回值返回的是借用的引用还是新的引用,需要根据文档仔细确认。否则,轻则出现内存泄漏,重则程序崩溃;

        Ⅱ Python中的数据结构与C++的有很大不同。Python常用的有tuple、list、dict,而C++常用的是vector、list、map,并且C++是强类型的。当C++与Python进行交互时,C++层希望操作Python数据结构就像操作C++ STL一样方便,而在Python脚本层,又希望C++传入的参数或返回值都是原生的Python数据;

        Ⅲ C++中常用指针传递对象,当嵌入Python时,需要把C++对象传递到Python中。

不同文件扩展名文件认识

.h                --- C++头文件

.cpp            --- C++源程序文件

.obj             --- Windows系统下的C++源程序经过编译后生成的目标文件(UNIX系统为.o)

.exe            --- Windows系统下的可执行程序(多个目标文件与库/资源文件的链接生成)

.dll   /*13*/  --- Windows系统下的动态链接库(Dynamic Link Library),.dll文件有如下用途:

                        ①代码共享:.dll文件中一些功能或服务的实现代码,多个应用程序可以共享同一个.dll文件,避免重复编写相同的代码;

                        ②动态链接:.dll文件是在运行时动态链接到应用程序中的;

                        ③扩展性:通过使用.dll文件,可以方便地向现有的应用程序添加新的功能或模块,而不需要修改或重新编译整个应用程序。只需将新的.dll文件提供给应用程序,然后在运行时加载和使用新的功能;

                        ④动态更新:由于.dll文件是独立于应用程序的,可以对.dll文件进行更新和升级,而不影响应用程序的正常运行。这使得软件的维护和升级变得更加灵活和方便。

.lib    /*14*/    --- Windows系统下的完全静态链接库(包含所有的导出声明和实现)或伴随.dll生成的动态.lib(动态.lib只包含一些函数索引信息,记录了.dll中那些函数的入口和位置)

.py              --- Python源程序文件

.pyd            --- 一般是C/C++编写的Python扩展模块,即Python的一个动态链接库(Linux 系统中一般为.so文件)

注意事项

       Ⅰ 完全静态.lib文件实际上就是任意个.obj文件的集合(任意个.obj文件链接生成一个完全静态.lib);

        Ⅱ .dll近似于.exe,只不过没有主函数(main)而不能单独执行。实际工程中,很多应用程序都并不是一个完整的单独可执行文件,它们被分割成一些单独的相对独立的动态链接库,只有在执行应用程序的时候,用到的.dll才会被调用。

参考资料:

官方文档

[1] Extending and Embedding the Python Interpreter — Python 3.9.17 documentation

[2] Python/C API Reference Manual — Python 3.9.17 documentation

[3] Welcome to Cython’s Documentation — Cython 3.0.7 documentation

Wikipedia

[4] https://zh.wikipedia.org/wiki/C%2B%2B(C++)

[5] https://zh.wikipedia.org/wiki/Python(Python)

参考书籍

[6] C++语言程序设计 / 郑莉,董渊编著.—5版.—北京:清华大学出版社,2020.11.

优秀博客及学习视频资源

[7] c++ 调用 python_哔哩哔哩_bilibili

[8] C++调用Python(混合编程)函数整理总结-CSDN博客

[9] Python与C/C++混合编程 - 知乎

[10] C++(Qt)与Python混合编程(一) - 知乎

[11] C++(Qt)与Python混合编程(二) - 知乎

[12] C++使用ffpython嵌入和扩展python-阿里云开发者社区

[13] Docs(C++调用Python脚本)

拓展资料

/*1*/ 站在巨人的肩膀上,C++开源库大全-阿里云开发者社区

/*2*/ github上总结的python资源列表【转】-阿里云开发者社区

/*3*/ 计算机基础------计算机语言分类(脚本语言引发的思考)-阿里云开发者社区

/*4*/ C++强大的背后-阿里云开发者社区

/*5*/ 你知道.c是如何变成.exe的吗 - 知乎

/*6*/ C/C++编译链接 - 知乎

/*7*/ Python PyInstaller 打包成 Win、Mac 应用程序(app / exe)-阿里云开发者社区

/*8*/ 回调函数详解-CSDN博客

/*9*/ https://zh.wikipedia.org/wiki/%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0(回调函数)

/*10*/ C++中的extern_c++ extern-CSDN博客

/*11*/ 1-Python介绍-阿里云开发者社区

/*12*/  C/C++中几种经典的垃圾回收算法_c 垃圾回收算法-CSDN博客

/*13*/ c++中什么叫dll文件,有什么用_c++推送数据dll文件-CSDN博客

/*14*/ 关于lib文件的介绍-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

no和not的应用场景

语法 后面直接跟名词:no 后面不是跟名词:not 案例

java struts2教务管理系统Myeclipse开发mysql数据库struts2结构java编程计算机网页项目

一、源码特点 java struts2 教务管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助 struts2 框架开发,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境 为TOMCAT7.0,Myeclipse8.5开发,数据库…

深度学习|2.11 向量化vectorization

2.11 向量化的作用 向量化可以使得向量中的每一个维度的数据进行并行计算,从而加快了神经网络的计算速度。 验证 其他

详解 MySql InnoDB 的 MVCC 实现机制

目录 一. 前言 二. 认识 MVCC 2.1. 什么是 MVCC? 2.2. 什么是当前读和快照读? 2.3. 当前读、快照读和 MVCC 的关系 2.4. MVCC 能解决什么问题,好处是什么? 2.5. 小结 三. MVCC 的实现原理 3.1. 隐式字段 3.2. undo 日志…

4-文献阅读-A Data-driven Base Station Sleeping Strategy Based on Traffic Prediction

目录 文献阅读—A Data-driven Base Station Sleeping Strategy Based on Traffic Prediction0、选这篇文章的原因1、文章的主要内容和贡献2、使用的数据集3、结果及分析4、郭郭有话说 文献阅读—A Data-driven Base Station Sleeping Strategy Based on Traffic Prediction 0…

一元函数微分学——刷题(12

目录 1.题目:2.解题思路和步骤:3.总结:小结: 1.题目: 2.解题思路和步骤: 注意两个y的区别即可 都可以在图中画出来,所以就非常好比较 3.总结: 理解两种y的区别即可 小结&…

【C#】知识点实践序列之Lock简单解决并发引起数据重复问题

欢迎来到《小5讲堂之知识点实践序列》文章,大家好,我是全栈小5。 这是2023年第3篇文章,此篇文章是C#知识点实践序列文章,博主能力有限,理解水平有限,若有不对之处望指正! 本篇在Lock锁定代码块基…

Kubernetes(k8s):Namespace详解

Kubernetes(k8s):Namespace详解 一、Namespace简介1.1 什么是Namespace1.2 Namespace的作用1.3 命名空间的分类 二、创建和管理Namespace2.1 创建Namespace2.2 管理Namespace 三、Namespace的实战应用3.1 部署多个项目3.2 环境隔离3.3 资源配…

JMeter 简单使用

JMeter 简介 Apache JMeter 是一款流行的性能测试工具,可以用来模拟用户行为并对系统进行压力测试。 安装 官方网站:http://jmeter.apache.org/ 在window下解压后, 运行 “bin/jmeter.bat” Jmeter 支持中文, 启动 Jmeter 后&…

SpringCloud微服务 【实用篇】| Dockerfile自定义镜像、DockerCompose

目录 一:Dockerfile自定义镜像 1. 镜像结构 2. Dockerfile语法 3. 构建Java项目 二: Docker-Compose 1. 初识DockerCompose 2. 部署微服务集群 前些天突然发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,…

【软件工程】设计概念

🍎个人博客:个人主页 🏆个人专栏: 软件工程 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 软件工程中的设计概念 概念: 结语 我的其他博客 前言 在数字时代的浪潮中,软件工程设计成为塑造创新…

PCBA电阻失效分析

一、案例背景 PCBA电阻使用一段时间后发生功能失效不良,据此情况,对失效电阻进行分析,明确失效原因。 二、分析过程 1、针对排阻的分析 数据通讯的主要连接点: 电阻测试结果: 测试结果:RP2、RP5 排阻第 3 …

基于YOLOv8的目标跟踪技术

💡💡💡本文摘要:介绍了YOLOv8自带的目标跟踪技术以及评价指标,并教会你如何在YOLOv8使用 1.YOLOv8自带两种跟踪方法 ultralytics/cfg/trackers/文件夹下 1.1 ByteTrack介绍 https://arxiv.org/pdf/2110.06864.pdf 摘…

【C++学习】:命名空间、输入输出和缺省参数全面解析

🎥 屿小夏 : 个人主页 🔥个人专栏 : C入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. 命名空间1.1 为什么需要命名空间?1.2 命名空间的定义1.3 命名空间特性1…

基于JAVA的创意工坊双创管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员端2.2 Web 端2.3 移动端 三、系统展示四、核心代码4.1 查询项目4.2 移动端新增团队4.3 查询讲座4.4 讲座收藏4.5 小程序登录 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的创意工坊双创管理…

「MySQL运维常见问题及解决方法」

「MySQL运维常见问题及解决方法」 一、查看MySQL数据库安装路径1.1、方式一 --SHOW VARIABLES LIKE basedir;1.2、方式二 --ps -ef | grep mysql 二、MySQL设置连接数与最大并发数2.1、永久生效--修改my.cnf文件2.2、临时生效--通过命令设置的全局变量 三、其他相关参数设置四、…

YOLOv5独家原创改进:提出一种新的Shape IoU,更加关注边界框本身的形状和尺度,对小目标检测也很友好 | 2023.12.29收录

💡💡💡本文改进:一种新的Shape IoU方法,该方法可以通过关注边界框本身的形状和尺度来计算损失,解决边界盒的形状和规模等固有属性对边界盒回归的影响。 💡💡💡对小目标检测涨点明显,在VisDrone2019、PASCAL VOC均有涨点 收录 YOLOv5原创自研 https://blog.cs…

Linux+nginx-前端部署的详细步骤

直奔主题 学废以下内容,前端也可以自己做部署啦~ Linux:大多数服务器都是使用Linux作为操作系统:稳定、安全、开源。finalShell工具:finalShell是一个方便管理远程服务器的工具,提供了可视化的操作配置界面。在和远程…

调用api接口异常的原因及解决方法

在进行接口调用时,调用有时会遇到各种异常情况,接口解决例如连接超时、异常因及返回值错误等。调用的原这些异常情况可能会导致程序无法正常运行,接口解决因此需要及时解决。异常因及本文将介绍。 一、接口解决连接超时 连接超时是异常因及…

mybatis-flex笔记

MyBatis-Flex 的增删改功能 - MyBatis-Flex 官方网站https://mybatis-flex.com/zh/base/add-delete-update.html https://gitee.com/hntianshu/mybatis-flex-test.githttp://xn--ces6a538pmb2a 一 新增数据 不忽略 null 值。 就是允许有null 忽略null 就是不允许有null BaseM…