1.2 动态链接库与API
yuyutoo 2024-11-26 10:37 2 浏览 0 评论
本节必须掌握的知识点:
kernel32.dll
user32.dll
gdi32.dll
■动态链接库
最早的软件开发过程,所有的功能实现都是有程序员独立完成的。在这个过程中,我们很快就会发现,有很多常用的功能模块是可以重复利用的,我们将其封装为功能函数。我们将这些功能函数独立编译成统一格式的OBJ目标文件,并存放于一个LIB库文件中。源程序中可以调用这些第三方功能函数,当编译器编译时,暂时将这些第三方功能函数的地址空下,待链接器链接时,在LIB库中查找对应的OBJ功能模块,并将其添加到源代码中,填写空下的函数地址。这就是我们所谓的静态链接库了。
在Windows操作系统中,采用的是另外一种形式的链接库,我们将特定功能的第三方功能函数封装到一个dll形式的库中,我们将其称为动态链接库。动态链接库dll文件通常保存在“C:\Windows\System32”系统目录下。源程序中同样直接调用第三方功能函数(需要头文件声明函数原型)。编译器编译链接时,会将第三方功能函数所在的dll动态链接库名称、函数名称、函数序号以及函数相对地址记录到一个PE文件(Windows指定的exe二进制格式文件)的节区。待编译后的EXE文件由操作系统加载到低2GB空间时,加载dll动态链接库(除了系统链接库之外,也可以是自定义的dll动态链接库)。此时,应用程序和dll动态链接库同处于一个4GB虚拟空间内,然后根据所引用的函数名或序号在动态链接库内查找该函数真实的地址,替换函数地址表内的相对地址,这样形成一个完整的程序就可以正常运行了。
为何要采用动态链接库这种形式呢?随着应用程序的功能越来越多,所引用的库函数也变得越来越多,如果继续采用静态链接库的形式,无疑会大大增加程序的体积,基于有限的存储空间和程序加载效率的考虑,设计动态链接库的形式可以很好地解决上述问题。动态链接库的缺点是对操作系统环境的依赖。
■API函数
对于程序员来说,Windows操作系统的功能完全由API(Application Programming Interface首字母的缩写,意思为程序之间的接口)来定义。API涵盖了应用程序所能调用的全部操作系统函数,以及相关的数据类型和结构。在Windows中,API还隐含了一种特殊的程序结构,我们将在后续章节中详细探讨这种程序结构。
早期的Windows 1.0版本只能支持不到450个函数,而今天则支持数千个API函数。
我们把windows 1.0到3.1版本称为win16,win95及98之后的所有NT版本称为win32。从win16到win32转化过程中大部分函数保持不变,但也有一些需要扩展,比如图形坐标点数值从win16的16位扩展为32位。此外,win16中有些函数调用返回的二维坐标点被压缩到一个32位的整数里,这在win32中就行不通了。为解决这些问题,win32增加了一些新的函数。
所有32位版本的windows既支持win16 API以保证和原先的程序兼容,也支持win32 API以运行新的应用程序。有意思的是,windows NT与win95和win98的工作方式不同。在WINDOWS NT中,win16的函数调用通过一个翻译层先被转换成win32的函数调用,然后再由操作系统来处理。而在windows95和windows 98中正好相反,win32的函数调用通过一个翻译层先被转换成win16的函数调用,然后再由操作系统来处理。
接下来,我们逐一介绍三个Windows应用程序必备的dll动态链接库。
1.2.1 kernel32.dll
kernel32.dll是一个Windows操作系统核心动态链接库文件。库中包含了九百多个API函数,这些API函数主要负责内存管理、进程和线程管理、调试、错误处理和时间处理等功能。
■内存管理:kernel32.dll包含了管理内存的API函数。例如:
●GlobalAlloc和LocalAlloc函数用于从堆中分配内存。
●GlobalFree和LocalFree函数用于释放之前分配的内存。
●VirtualAlloc和VirtualFree函数用于分配和释放大块的进程虚拟地址空间(4GB)中的内存。
●HeapAlloc和HeapFree函数用于管理堆中的内存。
●HeapCreate函数创建私有堆。
类似的虚拟空间和堆栈的操作函数还有很多,不再一一列举。
■进程和线程管理:Windows操作系统作为多任务系统,需要创建、管理、维护和切换多个任务。Windows操作系统是进程强相关的操作系统,进程与进程之间可以进行读写操作。Windows操作系统中的进程可以包含一个或多个线程,进程是一些资源的集合,进程内的所有线程可以共享这些资源。在多任务系统中,任务切换其实就是线程切换。可以是同一进程中的线程切换,也可以是不同进程间的线程切换。kernel32.dll包含的常用的进程和线程函数有:
●CreateProcess函数创建进程。
●CreateThread函数创建线程。
●CloseHandle函数减少一个内核对象计数。
●WaitForSingleObject函数检测内核对象信号状态。
●CreateEvent函数创建事件内核对象。
●TerminateProcess函数结束进程。
●TerminateThread函数结束线程。
■调试函数:kernel32.dll还包含了一些和调试相关的函数,包括进程间的远程读写。例如:
●DebugActiveProcess函数使调试程序能够附加到活动进程并对其进行调试。
●GetThreadContext函数可以检索指定线程的上下文。
●ReadProcessMemory函数从指定进程中的内存区域读取数据。
●WriteProcessMemory函数将数据写入到指定进程中的内存区域。
■错误处理:在程序开发中,难免会出现一些错误和异常,检测和处理这些错误和异常需要使用kernel32.dll中的函数。例如:
●SetUnhandledExceptionFilter函数安装一个顶层的全局异常处理程序。
●GetExceptionCode函数用于获取异常的类型。
●GetExceptionInformation函数用于获取异常的信息。
●RaiseException函数在调用线程中引发异常。
●GetLastError函数检索最后错误代码。
●若要访问消息字符串,需要使用 FormatMessage 函数。
■时间处理:Windows操作系统提供了各种各样的时间处理函数,这些函数无疑都是在动态链接库kernel32.dll中的。例如:
●系统时间函数GetSystemTime检索 UTC 格式的当前系统日期和时间。
●SetSystemTime函数设置当前系统时间和日期。
●本地时间函数GetLocalTime检索当前本地日期和时间。
●用于处理文件时间的函数GetFileTime检索指定文件或目录的创建、上次访问和上次修改的日期和时间。
●FileTimeToLocalFileTime函数将 UTC 文件时间转换为本地文件时间。●FileTimeToSystemTime函数将文件时间转换为系统时间格式。
1.2.2 user32.dll
user32.dll主要负责处理用户图形界面,是Windows用户界面相关应用程序接口。user32.dll中常用的API函数如下:
■窗口操作:
●CreateWindowEx函数用指定方式创建一个窗口。
●CreateMDIWindow函数创建一个多文档界面窗口。
●DestroyWindow函数销毁指定的窗口。
●FindWindow函数从类名或窗口名中返回一个相匹配的顶层窗口的句柄。
●GetWindow函数返回指定窗口的句柄。
●RegisterClass函数为以后调用CreatWindow函数注册一个窗口类。
■菜单操作:
●CreateMenu函数创建一个菜单,然后用AppendMenu函数填充菜单项。
●DestroyMenu 函数销毁指定的菜单。
●GetMenuItemInfo函数返回有关菜单项的信息。
●AppendMenu函数在给定菜单的尾不增加新项。
■对话框操作:
●CreateDialotParam函数从对话框模板资源中创建一个无模式对话框。
●DialogBoxParam 函数从对话框模板资源中创建一个模式对话框。
●MessageBox函数创建、显示并操作一个消息框。
■GUI对象操作:
●CreateCursor函数用指定大小、位模式、热点创建一个光标。
●CreateIcon 函数用指定大小、颜色和位模式创建一个图标。
●CopyRect函数拷贝一个矩形坐标。
●GetScrollInfo函数返回滚动条的参数,包括最小/最大滚动位置,页大小及拇指框的位置。
●LoadImage函数装入一个图标、光标或位图。
●SetScrollRange函数设置滚动条最大或最小位置值。
提示
【注】Windows对象可以分为GUI对象、GDI对象和内核对象三类。
GUI对象包括窗口、客户窗口、滚动条、菜单、标题栏等用户图形界面中的对象。
GDI对象包括画笔、画刷、字体、位图、路径、调色板等绘图工具。
内核对象包括进程、线程、事件、信号量、互斥量等内核中创建的对象。
■消息操作:
●GetMessage函数从指定线程的消息队列中检取一条消息。
●PeekMessage函数检查应用程序的消息队列。
●PostMessage函数在指定的窗口消息队列中放置一条消息。
●SendMessage函数把一消息发送给指定的多个窗口。
●TranslateMessage函数把虚键消息翻译为字符消息。
●DispatchMessage函数传送一个消息给指定的窗口过程。
1.2.3 gdi32.dll
gdi32.dll动态链接库用于图形设备接口(GDI)功能的实现。GDI是一个图形接口,负责处理Windows系统中的图形和字体操作,如绘制图形、显示文本、打印等操作。GDI函数有一个非常明显的特征是函数的第一个参数一定是设备环境上下文句柄(跟踪设备上下文地址的指针)。gdi32.dl中常用的API函数如下:
■GDI对象操作:
●CreateBitmap 函数创建具有指定宽度、高度和颜色格式的位图, (颜色平面和每像素位) 。
●CreateBrushIndirect 函数创建具有指定样式、颜色和图案的逻辑画笔。
●CreatePen 函数创建具有指定样式、宽度和颜色的逻辑笔。 笔随后可以选择到设备上下文中,并用于绘制线条和曲线。
●CreateSolidBrush 函数创建具有指定纯色的逻辑画笔。
●CreateCompatibleDC 函数创建与指定设备兼容的内存设备上下文 (DC) 。
●CreateDIBitmap 函数从 DIB 创建兼容位图 (DDB) ,并选择性地设置位图位。
●CreateFont 函数创建具有指定特征的逻辑字体。 随后可以选择逻辑字体作为任何设备的字体。
●CreatePalette 函数创建逻辑调色板。
●GetDC 函数检索设备上下文的句柄, (指定窗口的工作区或整个屏幕的 DC) 。
●getObject 函数 (wingdi.h) 检索指定图形对象的信息。
■绘图函数:
●LineTo 函数从当前位置绘制一条线,但不包括指定点。
●MoveToEx 函数将当前位置更新为指定点,并根据需要返回上一个位置。
●Rectangle 函数绘制矩形。 矩形使用当前笔轮廓,并使用当前画笔填充。
●RoundRect 函数绘制带圆角的矩形。 矩形使用当前笔轮廓,并使用当前画笔填充。
●Ellipse 函数绘制椭圆形。 椭圆的中心是指定边框的中心。 椭圆形使用当前笔轮廓,并使用当前画笔填充。
●CreateEllipticRgn 函数创建椭圆区域。
●CreatePolygonRgn 函数创建多边形区域。
●CreateRectRgn 函数创建矩形区域。
●DrawText 函数在指定矩形中绘制格式化文本。
●TextOut 函数使用当前所选字体、背景色和文本颜色在指定位置写入字符串。
●FillPath 函数关闭当前路径中所有打开的图形,并使用当前画笔和多边形填充模式填充路径的内部。
●FillRect 函数使用指定的画笔填充矩形。 此函数包括左边框和上边框,但不包括矩形的右边框和下边框。
●FrameRect 函数使用指定的画笔在指定矩形周围绘制边框。 边框的宽度和高度始终是一个逻辑单元。
●FrameRgn 函数使用指定的画笔在指定区域周围绘制边框。
●GetDIBits 函数检索指定兼容位图的位,并使用指定格式将其作为 DIB 复制到缓冲区中。
●PlayMetaFile 函数显示存储在指定设备上的给定 Windows 格式图元文件中的图片。PolyDraw 函数绘制一组线段和 B zier 曲线。
●PolyBezierTo 函数绘制一条或多条 B zier 曲线。
●PolylineTo 函数绘制一条或多条直线。
●SetMapMode 函数设置指定设备上下文的映射模式。 映射模式定义用于将页面空间单位转换为设备空间单位的度量单位,还定义设备的 x 和 y 轴的方向。
●BitBlt 函数将对应于像素矩形的颜色数据从指定的源设备上下文传输到目标设备上下文中。
●BeginPaint 函数准备用于绘制的指定窗口,并使用有关绘制的信息填充 PAINTSTRUCT 结构。
■打印输出函数:
●StartDoc 函数启动打印作业。
●EndDoc 函数结束打印作业。
●EndPage 函数通知设备应用程序已完成对页面的写入。 此函数通常用于指示设备驱动程序转到新页面。
●StartPage 函数准备打印机驱动程序以接受数据。
●GetPrinter 函数检索有关指定打印机的信息。
●EnumPrinters 函数枚举可用的打印机、打印服务器、域或打印提供程序。
相关推荐
- TCP协议原理,有这一篇就够了
-
先亮出这篇文章的思维导图:TCP作为传输层的协议,是一个软件工程师素养的体现,也是面试中经常被问到的知识点。在此,我将TCP核心的一些问题梳理了一下,希望能帮到各位。001.能不能说一说TC...
- Win10专业版无线网络老是掉线的问题
-
有一位电脑基地的用户,使用...
- 学习计算机网络需要掌握以下几方面基础知识
-
计算机基础知识操作系统:了解常见操作系统(如Windows、Linux)的基本操作和网络配置,例如如何设置IP地址、子网掩码、网关和DNS服务器等,以及如何通过命令行工具(如ping、tr...
- 网络工程师的圣经!世界级网工手绘268张图让TCP/IP直接通俗易懂
-
要把知识通俗地讲明白,真的不容易。——读者说TCP/IP从字面意义上讲,有人可能会认为TCP/IP是指TCP和IP两种协议。实际生活当中有时候也确实就是这两种协议。然而在很多情况下,它只是...
- 三分钟了解通信知识TCP与IP协议(含“通信技术”资料分享)
-
TCP/IPTCP/IP分层模型①应用层...
- 网闸与防火墙:网络安全设备的差异与应用
-
在网络安全领域,网闸(安全隔离网闸,GAP)和防火墙(Firewall)是两类重要的防护设备。尽管它们都服务于网络安全防护,但在设计理念、技术原理、安全效能及适用场景等方面存在显著差异,以下从五个维度...
- S7-300的TCP/IP通信
-
一、首先在项目中创建2个S7-300的站点;二、硬件组态中,设置合适的TCP/IP地址,在同一网段内;...
- 西门子S7-1500 PLC的 MODBUS TCP通信
-
MODBUSTCP使MODBUS_RTU协议运行于以太网,MODBUSTCP使用TCP/IP和以太网在站点间传送MODBUS报文,MODBUSTCP结合了以太网物理网络和网络标准TC...
- 系统规划与管理师新版备考必备:第7章考点思维导图解析
-
备考系统规划与管理师的小伙伴们,福利又来啦!今天为大家带来《系统规划与管理师(第2版)》第7章考点的思维导图,助你高效梳理重点,让备考更有方向!...
- TCP/IP、Http、Socket 有何区别与联系?
-
HTTP协议对应于应用层,Socket则是对TCP/IP协议的封装和应用(程序员层面上)。HTTP是应用层协议,主要解决如何包装数据。而我们平时说的最多的Socket是什么呢?实际上...
- 西门子PLC串口协议与以太网通信协议对比
-
西门子plc品牌众多,通信协议的类型就更多了,具体可分为串口协议和以太网通信协议两大类。...
- 网络编程懒人入门(十三):一泡尿的时间,快速搞懂TCP和UDP的区别
-
本文引用了作者Fundebug的“一文搞懂TCP与UDP的区别”一文的内容,感谢无私分享。1、引言...
- 程序员必备的学习笔记《TCP/IP详解(一)》
-
为什么会有TCP/IP协议在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别。就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样...
- 一文读懂TCP/IP协议工作原理和工作流程
-
简述本文主要介绍TCP/IP协议工作原理和工作流程。含义TCP/IP协议,英文全称TransmissionControlProtocol/InternetProtocol,包含了一系列构成互联网...
- 如何在 Windows 10 和 Windows 11 上重置 TCP/IP 堆栈
-
传输控制协议/Internet协议,通常称为TCP/IP,是您的WindowsPC如何与Internet上的其他设备进行通信的关键部分。但是当事情出错时会发生什么?你如何解决它?幸运的...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
推荐7个模板代码和其他游戏源码下载的网址
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)