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

一、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.mzph.cn/news/591053.shtml

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

相关文章

大数据背后的绿色收割:基于Hadoop的农产品价格信息智能分析

大数据背后的绿色收割:基于Hadoop的农产品价格信息智能分析 引言正文1. 数据获取与准备2. 数据清洗与处理3. Hadoop数据分析引擎的运用4. MySQL数据库的集成5. 创新性的可视化6. 结论与展望 结语 引言 随着信息技术的不断发展,农业领域也在数字化的浪潮…

electron预加载脚本

webPreferences 指定预加载脚本,可以使用部分node脚本 webPreferences: {preload: path.join(__dirname, "preload.js"),},创建preload.js 中 测试文件读取功能 const fs require(fs) const text fs.readFileSync(package.json, utf-8)console.log(text)报错,为了…

云计算复习提纲

第一章 大数据的概念:海量数据的规模巨大到无法通过目前主流的计算机系统在合理时间内获取、存储、管理、处理并提炼以帮助使用者决策 大数据的特点:①数据量大,存储的数据量巨大,PB级别是常态;②多样,数…

SpringBoot快速集成多数据源(自动版)

有些人因为看见所以相信,有些人因为相信所以看见 有目录,不迷路 前期准备实现演示参考 最近研究了一下多数据源,这篇博客讲的是简单模式,下篇博客预计写自动切换模式 前期准备 本篇博客基于SpringBoot整合MyBatis-plus&#xff0…

vue保姆级教程----深入了解Vuex的工作原理

📢 鸿蒙专栏:想学鸿蒙的,冲 📢 C语言专栏:想学C语言的,冲 📢 VUE专栏:想学VUE的,冲这里 📢 CSS专栏:想学CSS的,冲这里 &#x1f4…

Gen-AI 的知识图和分析(无需图数据库)

如今,图表比以往任何时候都更加相关和有用。由于目前正在发生的人工智能革命,工程师们正在考虑围绕 Gen-AI 的机会,利用具有动态提示、数据基础和屏蔽功能的开放 Gen-AI 解决方案,这进一步促使他们思考知识图谱等有效的解决方案。…

Ansible自动化运维(一)简介及部署、清单

👨‍🎓博主简介 🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 🐋 希望大家多多支…

Vue2 - Vue.observable 介绍

目录 1,介绍2,使用场景和 Vue 实例的区别 1,介绍 官网参考 可以让一个对象变成响应式数据。在 Vue 内部就是用它来处理传递给 Vue 的 data 对象,或是在单文件组件中 data() 返回的对象。 var vm new Vue({data: {count: 0} })…

MySQL数据库学习二

2 MySQL InnoDB 锁的基本类型 https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html 官网把锁分成了 8 类。所以我们把前面的两个行级别的锁(Shared and ExclusiveLocks),和两个表级别的锁(Intention Locks)…

游泳耳机到底怎么选?一文说全游泳耳机哪个好!

对于一个热爱游泳的人,每次游泳都希望找到一种好的方式来打发时间,同时也希望能够得到一些锻炼。在尝试了各种游泳装备之后,发现游泳耳机是一个非常不错的选择,不过市面上的游泳耳机鱼龙混杂,所以游泳耳机的选择需要综…

深度学习|2.11 向量化vectorization

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

超市订单管理系统

比较简单的超市订单管理系统

4.28 构建onnx结构模型-Unfold

前言 构建onnx方式通常有两种: 1、通过代码转换成onnx结构,比如pytorch —> onnx 2、通过onnx 自定义结点,图,生成onnx结构 本文主要是简单学习和使用两种不同onnx结构, 下面以 Unfold 结点进行分析 方式 方法…

电子书推荐|VMware 替代与升级攻略:技术路线、产品对比与用户实践

在进行 VMware 国产化替代时,您是否会遇到以下问题: 如何实现 VMware 整体架构/部分组件替换?是否可以不仅“为替换而替换”,而是同时实现架构的升级,带来更多业务价值?哪些国产方案具备 VMware 同等能力&…

vue3+ts+vite自定义组件上传npm流程

1. 创建项目 npm create vite 这里踩坑点: 运行vite生成的vue项目时报错“SyntaxError: Unexpected token ?? at “ 是因为node版本过低 电脑为windows11系统,我当时使用的版本node版本是14.21.3,如下图,后边安装了nvm版本…

PyTorch中常用的工具(3)TensorBoard

文章目录 前言3 可视化工具3.1 TensorBoard 前言 在训练神经网络的过程中需要用到很多的工具,最重要的是数据处理、可视化和GPU加速。本章主要介绍PyTorch在这些方面常用的工具模块,合理使用这些工具可以极大地提高编程效率。 由于内容较多&#xff0c…

【解决】电脑上的WIFI图标不见了咋整?

相信不少同学都遇到过这种情况:电脑上的wifi图标莫名不见了,甚至有时候还是在使用的中途突然断网消失的。 遇到这种情况一般有两种解决方案: 1. 在开机状态下长按电源键30秒以上 这种办法应该是给主板放电,一般应用在wifi6上面。…

计算机视觉与自然语言处理(Open AI)

1.语音识别技术 语音识别是将语音转换为文本的技术, 是自然语言处理的一个分支。通过特征的提取、模式的匹配将语音信号变为文本或命令,以实现机器识别和理解语音。 按照应用场景的不同,可以大致分为三类; • 电信级系统应用&…

树莓派(linux)使用Motion动作捕捉或实时获取视频

测试摄像头 查看系统是否识别了摄像头 $ lsusb 测试摄像头抓图(拍照) 安装 fswebcam sudo apt-get install fswebcam 抓拍一张图,存放与当前目录,并保存为 jpg 格式。 fswebcam /dev/video0 ./img1.jpg 查看摄像头效果 安装 luvcview …

Web前端第9章思维导图

本章内容是关于CSS样式属性,包含CSS单位、CSS字体样式、CSS文本样式、CSS颜色与背景、CSS列表样式、CSS盒模型。重点在于CSS盒模型、CSS文本样式、CSS字体样式。 1. CSS单位 绝对单位 磅(pt),pica(pc)、c…