messagebox看API

messagebox看API

2023年6月22日发(作者:)

下面我们来看看Windows平台下应用程序是怎么调用Windows提供的底层API服务运行的。

MessageBox()实际上在动态链接库里面, 中.

我们编写Win32SDK程序时,需要弹出对话框以作出友好的选择,MessageBox这个API函数就可以实现该功能。在开头要添加,因为其包含了众多的API函数声明头文件。为了探究这个小小的MessageBox是怎么弹出来的,我们右击MessageBox,选择“Go to definition of

MessageBox(转到定义) ”将打开中的#define MessageBox MessageBoxW定义行,我们继续对MessageBoxW右击“Go to definition of MessageBox(转到定义) ”将转到MessageBoxW的函数原型声明处:

int

WINAPI

MessageBoxW(

__in_opt HWND hWnd,

__in_opt LPCWSTR lpText,

__in_opt LPCWSTR lpCaption,

__in UINT uType);

我们在使用Windows窗口操作系统时,经常会蹦出大大小小的窗口,MessageBox只是Windows作为提示的对话框窗口单元。那么,MessageBoxW这个API函数到底在哪里实现的呢?应用程序是如何调用系统接口函数的呢?

动态链接库(.dll)

实际上Windows API函数是定义在一些DLL中的, DLL 实现了代码封装,从这个角度来看DLL才是真正意义上的API函数包,它是非开源Windows操作系统提供给我们的底层接口。DLL的编制与具体的编程语言及编译器无关。

动态链接库dll文件(Linux中与之对应的是的.so)存放在C:WINDOWSsystem目录和C:WINDOWSsystem32目录下,它在被应用程序调用时才同程序相链接。

其中最重要的DLL是、和这三个库文件。这三个库文件中的API函数都在Windows.h头文件中进行了声明。从功能上进行分类,(Windows XP USER API

Client DLL)定义了窗口管理函数,包括窗口的创建、显示、设置和移动等;(GDI Client DLL)定义了图形设备函数(GDI),实现与设备无关的绘图功能;(Windows NT BASE API

Client DLL)定义了系统服务函数,包括诸如内存调度、进程管理等与操作系统有关的底层功能。我们可以通过VC6自带的Depends工具或Dll函数查看器来一窥内幕,见下图。 DLL文件包括了具体实现的代码编译后的结果(二进制的机器码),而头文件就是打开.dll库文件的钥匙。所以我们若要使用MessageBoxW,只需#include (已被包含)。

VS编译器自带的标准函数库中声明的函数可以到C:Program FilesMicrosoft Visual Studio 8VCcrtsrc中查看相关实现源代码。例如strcat.c中实现了strcat和strcpy函数。有些函数的实现还是要调用底层API,例如C标准库函数create用于创建文件,但它是靠调用CreateFile()函数来完成创建文件功能的;beginthread(process.h,thread.c)需要调用 CreateThread()函数。

Windows将遵循下面的搜索顺序来定位 DLL: 包含EXE文件的目录>进程的当前工作目录>Windows系统目录>Windows目录>列在 Path 环境变量中的一系列目录.

如果你在本机编写一个Windows应用程序,移植到其他机子上(当然也是Windows操作系统),有可能因为缺少相关DLL文件而无法执行。因为DLL是动态链接,就是随用随加载,这就是为什么我们玩3D游戏时经常弹出缺少d3dx9***.dll的错误提示。如果启动的程序调用了一个过期的DLL文件或不匹配的DLL文件,则会出现“未定义的动态链接调用”消息。

动态链接库除了实现代码的共享外,其模块封装特性使得应用程序在调用一个DLL的不同版本时,只要导出的函数名相同就不必进行重新编译链接。这样,软件产品在更新或升级时,客户程序不必进行改动。在开发软件产品时,对于通用功能的函数,一般以DLL的形式来实现。Windows设备驱动程序就是体现上述特点的动态链接库。

动态链接库的调用方式又分为隐式调用(也称静态调用,需要.lib文件)和显式调用(也称动态调用,LoadLibrary->GetProcAddress->FreeLibrary)。

静态链接库(.lib)

在早期库的组织形式相对简单,里面的目标代码只能够进行静态链接,所以我们称为“静态库”,静态库的结构比较简单,其实就是把原来的目标代码放在一起,链接程序LINK根据每一份目标代码的符号表查找相应的符号(函数和变量的名字),找到的话就把该函数里面需要定位的进行定位,然后将整块函数代码放进可执行文件里,若是找不到需要的函数就报错退出。标准Turbo C2.0中的C库函数,例如scanf、printf、memcpy、strcpy等,就是使用的静态库技术。

静态链接lib库(Linux中与之对应的是的.a)的两个特点:

#1链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用磁盘空间较大。

#2如果有多个(调用相同库函数的)进程在内存中同时运行,内存中就存有多份相同的库函数代码,因此占用内存空间较多。

以下是C程序的编译链接过程:(1)执行cl /c main.c;cl /c lib1.c;cl /c lib2.c生成了 三个文件;(2)执行link /lib ;link /lib #生成了2个文件 ;(3)执行link

生成.

我们可以用记事本打开C:Program FilesMicrosoft Visual StudioVC98Lib中的文件,其中有

__imp__MessageBoxA@16 _MessageBoxW@16 // 这里16为参数的字节数

_MessageBoxW@16 / 889206797

静态链接库lib文件中存放的是接口函数申明的入口地址,dll中存放的是函数实体!当我们隐式调用dll时,需要在Link选项指明其对应的lib库。lib告诉编译器你的dll都导出了什么函数,以及这些函数的地址名称,运行的时候就根据这些信息到dll里面去找。

实际上用VC6.0新建一个Win32 Console Application时,我们查看Project Settings—>Link—>Object/library modules中发现VC默认已连接了、、等常用的lib文件。如果需要显式设置的话,比如在网络编程中需要添加WS2_库,则可以在文件的开头使用 #pragma comment(lib,"WS2_")命令。

在编写MFC项目时,我们打开Project Settings—>General的Microsoft Foundation Classes,里面有两种链接方式:Use MFC in a Static Library ,Use MFC in a Shared Library。对应在Visual

Studio 2005中项目属性—>配置属性—>常规—>MFC的使用中设置链接方式。

如果选择Use MFC in a Shared Library的话,你编译后的程序中不包含MFC库,所以文件会比较小,但是如果你的程序直接移到一个没有安装过MFC的机器上时,可能会导致找不到MFC的DLL,故发布时要带MFC得DLL文件。如果选择Use MFC in a Static Library,那么编译后的程序就直接包含了调用MFC的部分的库,文件可能会大一些,但是可以直接移到其他机器上运行,即发布时不用带MFC的DLL文件。

下面我们来看看Windows平台下应用程序是怎么调用Windows提供的底层API服务运行的。

我们编写Win32SDK程序时,需要弹出对话框以作出友好的选择,MessageBox这个API函数就可以实现该功能。在开头要添加,因为其包含了众多的API函数声明头文件。为了探究这个小小的MessageBox是怎么弹出来的,我们右击MessageBox,选择“Go to definition of

MessageBox(转到定义) ”将打开中的#define MessageBox MessageBoxW定义行,我们继续对MessageBoxW右击“Go to definition of MessageBox(转到定义) ”将转到MessageBoxW的函数原型声明处:

int

WINAPI

MessageBoxW(

__in_opt HWND hWnd,

__in_opt LPCWSTR lpText,

__in_opt LPCWSTR lpCaption,

__in UINT uType);

我们在使用Windows窗口操作系统时,经常会蹦出大大小小的窗口,MessageBox只是Windows作为提示的对话框窗口单元。那么,MessageBoxW这个API函数到底在哪里实现的呢?应用程序是如何调用系统接口函数的呢?

动态链接库(.dll)

实际上Windows API函数是定义在一些DLL中的, DLL 实现了代码封装,从这个角度来看DLL才是真正意义上的API函数包,它是非开源Windows操作系统提供给我们的底层接口。DLL的编制与具体的编程语言及编译器无关。 动态链接库dll文件(Linux中与之对应的是的.so)存放在C:WINDOWSsystem目录和C:WINDOWSsystem32目录下,它在被应用程序调用时才同程序相链接。

其中最重要的DLL是、和这三个库文件。这三个库文件中的API函数都在Windows.h头文件中进行了声明。从功能上进行分类,(Windows XP USER API

Client DLL)定义了窗口管理函数,包括窗口的创建、显示、设置和移动等;(GDI Client DLL)定义了图形设备函数(GDI),实现与设备无关的绘图功能;(Windows NT BASE API

Client DLL)定义了系统服务函数,包括诸如内存调度、进程管理等与操作系统有关的底层功能。我们可以通过VC6自带的Depends工具或Dll函数查看器来一窥内幕,见下图。

DLL文件包括了具体实现的代码编译后的结果(二进制的机器码),而头文件就是打开.dll库文件的钥匙。所以我们若要使用MessageBoxW,只需#include (已被包含)。

VS编译器自带的标准函数库中声明的函数可以到C:Program FilesMicrosoft Visual Studio 8VCcrtsrc中查看相关实现源代码。例如strcat.c中实现了strcat和strcpy函数。有些函数的实现还是要调用底层API,例如C标准库函数create用于创建文件,但它是靠调用CreateFile()函数来完成创建文件功能的;beginthread(process.h,thread.c)需要调用 CreateThread()函数。

Windows将遵循下面的搜索顺序来定位 DLL: 包含EXE文件的目录>进程的当前工作目录>Windows系统目录>Windows目录>列在 Path 环境变量中的一系列目录.

如果你在本机编写一个Windows应用程序,移植到其他机子上(当然也是Windows操作系统),有可能因为缺少相关DLL文件而无法执行。因为DLL是动态链接,就是随用随加载,这就是为什么我们玩3D游戏时经常弹出缺少d3dx9***.dll的错误提示。如果启动的程序调用了一个过期的DLL文件或不匹配的DLL文件,则会出现“未定义的动态链接调用”消息。

动态链接库除了实现代码的共享外,其模块封装特性使得应用程序在调用一个DLL的不同版本时,只要导出的函数名相同就不必进行重新编译链接。这样,软件产品在更新或升级时,客户程序不必进行改动。在开发软件产品时,对于通用功能的函数,一般以DLL的形式来实现。Windows设备驱动程序就是体现上述特点的动态链接库。

动态链接库的调用方式又分为隐式调用(也称静态调用,需要.lib文件)和显式调用(也称动态调用,LoadLibrary->GetProcAddress->FreeLibrary)。

静态链接库(.lib)

在早期库的组织形式相对简单,里面的目标代码只能够进行静态链接,所以我们称为“静态库”,静态库的结构比较简单,其实就是把原来的目标代码放在一起,链接程序LINK根据每一份目标代码的符号表查找相应的符号(函数和变量的名字),找到的话就把该函数里面需要定位的进行定位,然后将整块函数代码放进可执行文件里,若是找不到需要的函数就报错退出。标准Turbo C2.0中的C库函数,例如scanf、printf、memcpy、strcpy等,就是使用的静态库技术。

静态链接lib库(Linux中与之对应的是的.a)的两个特点:

#1链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用磁盘空间较大。

#2如果有多个(调用相同库函数的)进程在内存中同时运行,内存中就存有多份相同的库函数代码,因此占用内存空间较多。

以下是C程序的编译链接过程:(1)执行cl /c main.c;cl /c lib1.c;cl /c lib2.c生成了 三个文件;(2)执行link /lib ;link /lib #生成了2个文件 ;(3)执行link

生成.

我们可以用记事本打开C:Program FilesMicrosoft Visual StudioVC98Lib中的文件,其中有 __imp__MessageBoxA@16 _MessageBoxW@16 // 这里16为参数的字节数

_MessageBoxW@16 / 889206797

静态链接库lib文件中存放的是接口函数申明的入口地址,dll中存放的是函数实体!当我们隐式调用dll时,需要在Link选项指明其对应的lib库。lib告诉编译器你的dll都导出了什么函数,以及这些函数的地址名称,运行的时候就根据这些信息到dll里面去找。

实际上用VC6.0新建一个Win32 Console Application时,我们查看Project Settings—>Link—>Object/library modules中发现VC默认已连接了、、等常用的lib文件。如果需要显式设置的话,比如在网络编程中需要添加WS2_库,则可以在文件的开头使用 #pragma comment(lib,"WS2_")命令。

在编写MFC项目时,我们打开Project Settings—>General的Microsoft Foundation Classes,里面有两种链接方式:Use MFC in a Static Library ,Use MFC in a Shared Library。对应在Visual

Studio 2005中项目属性—>配置属性—>常规—>MFC的使用中设置链接方式。

如果选择Use MFC in a Shared Library的话,你编译后的程序中不包含MFC库,所以文件会比较小,但是如果你的程序直接移到一个没有安装过MFC的机器上时,可能会导致找不到MFC的DLL,故发布时要带MFC得DLL文件。如果选择Use MFC in a Static Library,那么编译后的程序就直接包含了调用MFC的部分的库,文件可能会大一些,但是可以直接移到其他机器上运行,即发布时不用带MFC的DLL文件。

发布者:admin,转转请注明出处:http://www.yc00.com/news/1687428140a9288.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信