[Python进阶] 混合编程

2.22 混合编程

2.22.1 什么是混合编程

所谓的混合编程就是指在一个大型项目中,因为要涉及到多个方面,单独使用某一种语言进行开发已经不能满足要求,可能在某一个模块中,需要用A语言编写一部分,而用B语言编写另外的部分。像这种使用两种或两种以上的程序设计语言来开发应用程序的过程就称为混合编程。
至今为止,计算机上流行的程序设计语言有多种,它们有各自的优势和不足,混合编程可以充分利用各种程序设计语言的优势。混合编程的关键问题是参数传递。

2.22.2 Python和C语言混合编程

Python和C语言混合编程是指在一个项目中同时使用Python和C语言来编写代码,并且两种语言之间进行交互和通信。
混合编程的目的是充分发挥各种语言的优势,使得程序能够更高效地运行和更灵活地开发。Python通常被用于开发高级逻辑、数据处理或用户界面等功能,而C语言则常用于底层系统编程、性能优化和硬件驱动等方面。
通过混合编程,Python可以调用C语言编写的底层库,从而提高程序的性能。同时,Python也可以作为高级语言调用C语言的接口,实现对底层的控制和扩展。
此外,混合编程还可以利用Python丰富的包管理工具和生态系统,使得C语言项目能够更好地集成进Python开发环境中,易于维护和扩展。
总之,混合编程结合了Python的高级特性和C语言的低级能力,使得开发者能够在不同需求和场景下选择合适的工具,达到更好的开发效果。

2.22.2.1 什么是windows API

Windows API(Application Programming Interface,应用程序编程接口)是微软公司为 Windows 操作系统提供的一组函数和过程的集合。它允许开发人员使用编程语言与操作系统交互,以创建各种类型的应用程序,如桌面应用、设备驱动程序、服务等。
Windows API 提供了丰富的功能,包括窗口管理、图形用户界面、文件系统、网络通信、多媒体处理、安全性等。开发人员可以使用这些函数和过程来操作窗口、处理用户输入、读写文件、进行网络传输、播放音频视频等。通过调用 Windows API,开发人员可以利用操作系统提供的底层功能,实现更加灵活和高效的应用程序开发。
常见的编程语言如C++、C#、VB.NET等都支持使用 Windows API 进行开发。开发人员可以参考微软的文档和示例代码来学习和使用 Windows API。

2.22.2.2 库文件和头文件

库文件(Library Files)是包含预编译的可重用二进制代码的文件。这些库可以包含函数、类、变量和其他可供程序使用的代码。当开发人员需要使用特定功能时,他们可以链接相应的库文件到他们的应用程序中,以便能够调用库中定义的函数和使用库中提供的功能。
头文件(Header Files)是包含外部库或模块中函数、数据结构和常量的声明的文件。这些声明使得开发人员可以了解如何正确地使用特定库或模块,并通过函数名、参数和返回类型来引导编译器,在编译时将相应的函数、结构或常量与其实际定义匹配起来。

开发人员使用头文件可以将外部库的功能集成到他们的代码中,并确保他们正确地使用这些功能。他们可以使用头文件来声明某个函数或变量,并在编译时将这些声明链接到相关的库文件,从而在运行时获得所需的功能。
库文件和头文件的区别
头文件(Header files)通常具有.h作为扩展名,并包含了函数和数据结构的声明(declaration)。它们描述了API函数和数据结构的名称、参数和返回值等信息,但没有实际的代码实现。头文件的主要作用是告诉编译器这些函数和数据结构的存在和定义,使得程序能够正确地调用和使用它们。程序在编译阶段会通过预处理命令(例如#include)将头文件中的声明插入到源代码中。
库文件(Library files)通常具有.lib或.dll作为扩展名。它们包含了API函数和数据结构的实际代码实现,以供程序在运行时调用。库文件可以分为静态库(Static libraries)和动态库(Dynamic libraries)。静态库在编译时被链接到程序中,使得程序¥¥运行,不需要依赖外部库文件。动态库则在运行时被动态加载并链接,多个程序可以共享同一个动态库文件,减小了可执行文件的大小。
总结起来,头文件用于声明API函数和数据结构的接口,使得程序能够在编译阶段正确地调用和使用它们;而库文件则包含了API函数和数据结构的实际代码实现,供程序在运行时调用。通过引用头文件和链接库文件,开发者可以方便地使用Windows API提供的各种功能。
常见的头文件

头文件说明
windows.h所有windows头文件的集合
windef.hwindows数据类型
winbase.hkernel32的API
wingdi.hgdi32的API
winuser.huser32的API
winnt.hUNICODE字符集支持

Windows库文件

库文件说明
kernel32.dll提供了核心的API,例如:进程、线程、内存管理等
uers32.dll提供了窗口、消息等API
gdi32.dll绘图相关的API
2.22.2.3 SDK

SDK是指软件开发工具包(Software Development Kit),它是一组用于开发软件应用程序的工具和资源的集合。SDK包含了编写、测试和调试应用程序所需的库文件、示例代码、文档和相关工具。通过使用SDK,开发人员可以更快地开发出高质量的Windows应用程序,并且能够与操作系统和其他软件进行交互和协作。SDK通常提供了一系列API(应用程序接口),开发人员可以通过调用这些API来访问操作系统的功能和服务。

2.22.2.4 MFC

MFC全称Microsoft Foundation Class(微软基础类库),是微软公司提供的一套C++编程框架,用于Windows操作系统上的图形用户界面(GUI)应用程序开发。MFC包含了一系列的类和函数,简化了应用程序的开发过程,并提供了丰富的界面元素、事件处理、与操作系统交互的功能。通过使用MFC,开发人员可以更方便地创建和管理窗口、对话框、控件以及其他GUI元素,并实现各种交互效果和功能。MFC在Windows平台开发中得到广泛应用,特别适合使用C++进行项目开发的开发人员。

2.22.3 Python和C语言混合编程方案 todo

ctype模块中含有的基本类型与C语言类似,下面是几个基本的数据类型的对照:
Ctypes数据类型 C数据类型
c_char char
c_short short
c_int int
c_long long
c_float float
c_doule double
c_void_p void *

2.22.3.1 使用Python标准库ctypes

使用标准库ctypes直接调用C/C++编写的动态链接库。这是最简单易用的方案。Python程序员只要知道这些动态链接库函数的名称、参数类型与返回值类型就能简单地调用它。
而且,当你传入参数时,ctypes模块会自动地把Python的对象成为C/C++所对应的参数类型。
示例一:调用Windows的API:

# 定义参数类型与函数名称
import ctypes
from ctypes.wintypes import UINT, DWORDGetLastInputInfo = ctypes.windll.user32.GetLastInputInfoclass LASTINPUTINFO(ctypes.Structure):_fields_ = [("cbSize", UINT), ("dwTime", DWORD)]# 开始调用DLL导出的函数
def getLastInputTime_nt():info = LASTINPUTINFO()info.cbSize = ctypes.sizeof(info)info.dwTime = 0if not GetLastInputInfo(ctypes.byref(info)):raise WindowsError("")
return info.dwTimeprint(getLastInputTime_nt())

17230812

在这里展示了如何构造Windows的API所需要的结构体,如何填充结构体并分析返回值。
ctypes还能将Python函数提供给C/C++代码作为回调函数。
方案优势
不需要程序员熟悉C/C++语言,不需要安装一个C/C++的编译器,它通过操作系统的接口直接操作C/C++代码。而且ctypes是标准库的一部分,只要安装了Python就可以直接使用。
方案劣势
1、ctypes不能简单调用C++程序,因为C++在编译的时候使用了name mangling这个技术来实现函数的重载。C++会自动地为类的成员函数加上类名前缀。
2、对于list, set之类的数据类型,ctypes不能识别并自动地在Python与C/C++数据类型之间转换。C/C++部分不能识别Python数据类型,这时候只能用Python语言来编写转换代码。如果数据量较大,或者调用很频繁,转换代码反而会浪费很多的资源。
示例二:调用Windows动态库中的函数删除文件

from ctypes import windlldll = windll.LoadLibrary("Kernel32.dll")
dll.DeleteFileW('1.txt')

示例三:将Python数据类型显示转换成C格式

import ctypes
from icecream import icnum = ctypes.c_int(0)
ic(num, type(num))

16:51:50|> num: c_long(0), type(num): <class ‘ctypes.c_long’>

示例四:调用windows的API弹出对话框

from ctypes import windlldll = windll.LoadLibrary("user32.dll")
dll.MessageBoxW(0, '内容', '标题', 0)
2.22.3.2 使用Cython

使用Cython语言,一种类似于Python语言的一种新型语言编写预定功能的代码,然后将这些代码转换成为C语言编译成为Python语言可以直接调用的二进制模块。Cython语言是融合Python语言与C语言的一种新型语言。它本身能够理解Python语言的语法,然后在其基础上增加了某些C语言的语法,以便更精细地控制数据类型与指针。基本兼容Python语法是这个解决方案最大的特点。很多时候,Python程序员只要在旧的代码中简单地声明一下代码中所使用的参数、变量的类型,就能把立即为旧的Python程序提速。

Cython提供了一个名为pyximporter的工具,能够在安装了C/C++编译器的计算机上面为简单的Cython程序直接生成相应的Python模块。这使得Cython的使用与普通的Python程序一样简单。比如下面这段代码,直接保存为myhello.pyx即可被调用。

#myhello.pyx
def sayHelloTenTimes():cdef int i #只要简单地为变量标识类型即可加速循环。for i in range(0, 10):print("hello, world!")

$ python

import pyximport; pyximport.install()
import myhello
myhello.sayHelloTenTimes()

由此可见,Cython非常容易使用。而且不仅能够处理C语言的模块,还能处理C++的模块——虽然没有直接支持虚函数之类的完整C++特性。因为它不直接使用C/C++语法,而是另外设计比C/C++更简洁优雅的新型语法,因此,对于不熟悉C/C++的程序员来说有很大的吸引力。相比ctypes来说,因为参数类型转换更加智能与高效,所以通常能够提升更多的效率。

劣势呢,所谓用Python程序员所熟练的语法来编写高速的运算代码,乍一听相当地有吸引力。但是如果想要更深入地控制内存与数据结构时,程序员可能会发现,现在他不得不熟练地掌握C/C++语言,然后用Cython的语法写出来。以程序员们懒惰的性格,这反而是件难以忍受的事件。这或许是Cython本身并不大流行的主要原因吧。

2.22.3.3 使用boost.python

使用boost.python。有意思的是,与ctypes/Cython形成鲜明的对比,boost.python倾向于让C++程序员拥有更熟悉的编程环境。它让C++程序员使用他所熟悉的C++语法直接控制Python的数据结构,调用Python的解释器。它没有像Cython那样发明新的语法,而是直接使用C++的语法,编写供Python使用的接口。与Cython同样的道理,它的效率优胜于ctypes。

与Cython/SWIG/SIP等方案相比,程序员只需要学习C/C++与Python两种语言。另外,与本文提到的几种解决方案相比,它非常适合在主要由C++编写的程序中控制Python代码。不仅功能更强大、效率还更高。如此神奇的解决方案会有什么劣势呢?某些人可能不同意吧,老鱼一听说它依赖于boost就蔫了,感觉编译与学习庞大又奇怪的boost非常浪费生命。

2.22.3.4 使用SWIG或者SIP

使用SWIG或者SIP,通过编写一个接口文件,使用类似于C/C++语法——声明函数、类型的信息,然后使用特殊的工具为C/C++的代码生成Python的接口代码。这些接口代码能够在Python与C/C++之间的数据结构转换。最终编译这些接口代码,成为Python的二进制模块。SWIG与SIP的接口文件与C/C++的头文件非常相似。

这两种工具差不多,因为。本质上,他们都与Cython类似,都使用了中间语言来生成转换代码。但SWIG/SIP能够在他们的接口文件中嵌入C/C++,能够让程序员仔细地调节数据类型的转换过程。在使用上,它比Cython的层次更低,更接近于Python本身提供的API。

SWIG能够为多种脚本语言生成转换代码。而SIP则专门针对Python与C++。此外,SIP本身是作为PyQt的专门工具来开发的,因此它能够理解Qt的signal/slot。从应用项目上来看,SWIG似乎会更广泛一点。而SIP,目前所见的项目基本都与PyQt相关。据说SWIG对于C++的支持不好,不知道有没有人来说一下呢。相比之下,SIP对于C++的支持非常完善,诸如虚函数、protected member function、模版、析构函数、异常等特性都得到良好的支持。而且SIP支持Python的GIL,还拥有一个使用Python编写的编译系统。可能会更方便一点。

然而这种方案毕竟要学习一种新的语言,所以从表面上来看不如Cython和boost.python讨喜。当程序员想要仔细地调节类型转换代码的时候,需要学习SWIG/SIP的内部机制,被限定使用特殊的变量名。这使得这种方案的学习曲线相对较高。

2.22.3.5 直接使用Python的API

直接使用Python的API,可以称之为最终解决方案。Cython, SWIG, SIP的接口文件转换后所生成的C/C++代码实际上都使用Python的API。与其它方案相比,这种方案相当地繁复,必须为每次函数调用编写数据转换代码,还要操心Python对象的引用计数。我觉得这种方案一无是处,这时就不再多讲了。其它的工具pybindgen不知道什么情况。有兴趣的话可以看看。

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

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

相关文章

SpringBoot使用classfinal-maven-plugin插件加密Jar包

jar包加密 1、在启动类的pom.xml中加入classfinal-maven-plugin插件 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><…

算法沉淀——动态规划之子数组、子串系列(上)(leetcode真题剖析)

算法沉淀——动态规划之子数组、子串系列 01.最大子数组和02.环形子数组的最大和03.乘积最大子数组04.乘积为正数的最长子数组长度 01.最大子数组和 题目链接&#xff1a;https://leetcode.cn/problems/maximum-subarray/、 给你一个整数数组 nums &#xff0c;请你找出一个具…

计算机设计大赛 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c…

vue3使用elementPlus进行table合并处理

elementPlus中table合并部分列 虚拟数据中公司下有多个客户&#xff0c;公司一样的客户&#xff0c;公司列需要合并&#xff0c;客户如果一样也需要合并进行展示&#xff0c;效果展示 const tableData ref([])自定定义自已想要的数据&#xff0c;一般都是通过接口拿到 //table…

springboot/ssm中医药店管理系统Java中药品出入库管理系统web

演示视频&#xff1a;https://www.bilibili.com/video/BV1rS421A7Ht/ 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&…

No module named ‘transformers.models.auto.tokenization_auto‘

transformers包安装 !pip install pytorch-transformers代码 from transformers import AutoTokenizer tokenizer AutoTokenizer.from_pretrained("gpt2")报错&#xff1a; No module named ‘transformers.models.auto.tokenization_auto’ 解决方案&#xff1a…

ubuntu+QT+ OpenGL环境搭建和绘图

一&#xff0c;安装OpenGL库 安装OpenGL依赖项&#xff1a;运行sudo apt install libgl1-mesa-glx命令安装OpenGL所需的一些依赖项。 安装OpenGL头文件&#xff1a;运行sudo apt install libgl1-mesa-dev命令来安装OpenGL的头文件。 安装GLUT库&#xff1a;GLUT&#xff08;Ope…

亚马逊巨头都在用的自养号大法,赶快get!

随着时间的推移&#xff0c;越来越多做亚马逊生意的朋友开始意识到自养号的重要性。拥有自养号意味着掌握了一手资源&#xff0c;这种自主性让人感到更安全。高权重的买家号可以享有更多的操作权限&#xff0c;也能获得更好的效果。然而&#xff0c;要想成功地养好自养号并不是…

mybatis---->tx中weekend类

&#x1f64c;首先weekend可不是mybatis中的类呦~~&#x1f64c; 它是来自于mybatis的一个扩展库&#xff01; 如果你要在springboot中使用&#xff0c;需要引入以下依赖~~ <dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot…

滥用生成式人工智能的安全威胁的应对

文章目录 前言一、生成式人工智能滋生了恶意大模型的新威胁(一)对维护国家安全提出新挑战(二)对行业应用创新造成新冲击(三)对生产生活方式带来新威胁二、生成式人工智能安全治理难点(一)包容审慎存在失衡,政策尺度有待细化(二)协同治理能力不足,联动合力有待提升(…

蓝桥杯刷题1

目录 1. 平方和 2. 门牌制作 3. 卡片 4. 分数 5. 星期一 6. 顺子日期 1. 平方和 题目描述&#xff1a;小明对数位中含有2、0、1、9 的数字很感兴趣&#xff0c;在1 到40 中这样的数包 括1、2、9、10 至32、39 和40&#xff0c;共28 个&#xff0c;他们的和是574&#x…

Netty权威指南——基础篇2(NIO编程)

1 概述 与Socket类和ServerSocket&#xff0c;NIO也提供了SocketChannel和ServerSocketChannel两种不同的套接字通道实现。这两种新增的通道都支持阻塞和非阻塞两种模式。阻塞模式使用简单&#xff0c;但性能和可靠性都不好&#xff0c;非阻塞模式则正好相反。一般来说&#xf…

python Matplotlib Tkinter-->导出pdf报表

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 reportlab 4.0.9 import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk import tkinter as tk import tkinter.messagebox as messagebox impor…

你知道哪里有Alzet购买吗?

Alzet Osmotic Pumps 是 ALZA 公司于二十世纪七十年代发明的一种用于体内药物缓释的工具。ALZA公司是一家著名的药物研发公司&#xff0c;由其研发的 Alzet 植入式胶囊渗透压泵一开始是用于公司内部和相关科研机构做药物测试用的&#xff0c;但是不久之后&#xff0c;由于渗透压…

46.仿简道云公式函数实战-文本函数-CHAR

1. CHAR函数 函数可将计算机其他类型的数字代码转换为字符。 2. 函数用法 CHAR(number) CHAR 函数可将计算机其他类型的数字代码转换为字符。 Number&#xff1a;用于指定字符的数字。 3. 函数示例 CHAR(10)&#xff0c;即返回值为换行字符"\n"。 目前仿简道…

电脑背景图片怎么设置?这个方法让你一目了然

电脑背景图片的设置是个性化电脑桌面的重要步骤之一。一张美观的背景图片不仅可以为电脑带来视觉愉悦&#xff0c;还能反映个人品味和风格。在本文中&#xff0c;我们将介绍电脑背景图片的设置方法&#xff0c;共包括三种方式&#xff0c;通过分步骤详细说明&#xff0c;帮助用…

【重温设计模式】适配器模式及其Java示例

【重温设计模式】适配器模式及其Java示例 适配器模式的介绍 在软件开发的世界里&#xff0c;设计模式如同是我们的罗盘&#xff0c;指引着我们在复杂的代码海洋中航行。而其中的适配器模式&#xff0c;就如同是我们手中的万能钥匙&#xff0c;让我们能够灵活应对各种各样的设…

解决Maven爆红以及解决 Idea 卡在 Resolving问题

关于 Idea 卡在 Resolving&#xff08;前提是Maven的setting.xml中配置好了阿里云和仓库&#xff09; 参考文章https://blog.csdn.net/jiangyu1013/article/details/95042611 解决Maven爆红参考文章https://devpress.csdn.net/beijing/656d993b76f0791b6eca7bb0.html?dp_toke…

IP 电话

1 IP 电话概述 IP 电话是在互联网上传送多媒体信息。 多个英文同义词&#xff1a; VoIP (Voice over IP) Internet Telephony VON (Voice On the Net) 1.1 狭义的和广义的 IP 电话 狭义的 IP 电话&#xff1a;指在 IP 网络上打电话。 广义的 IP 电话&#xff1a;不仅仅是…

路由器端口映射如何配置?

在网络通信中&#xff0c;路由器是一个重要的设备&#xff0c;它负责将数据包从一个网络传输到另一个网络。路由器的端口映射配置是一种重要的设置&#xff0c;可以使外部网络中的计算机通过访问路由器上的特定端口与内部网络中的计算机进行通信。本文将介绍什么是路由器端口映…