Windows链接库认知->大学不曾接触到的知识

前言

       如果用一个隐喻来形容链接库,我觉得更像一些可从武器上拆解的功能属性道具。调用链接库为了什么,为的是使用该定义好的功能函数。(只限于个人觉得哈)

动态连接库的分类

      MFC(Microsoft Foundation Classes)是微软公司提供的一个基础类库,以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含大量windows句柄封装类和很多windows的内建空间和组件的封装类
      Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)
      非MFC动态库不采用MFC类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;
      MFC规则DLL包含一个继承来自CWinApp的类,但其无消息循环;
      MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类库所编写的应用程序所调用。

编写动态连接库原则

对动态连接库:
1.DLL的编制与具体的编程语言及编译器无关
      只要遵循规定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。
      windows提供的DLL(其中包括了windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C++还是Delphi。
2.动态连接库随处可见
      在windows目录下的system32文件夹中看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。
      kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。
      一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll这个动态链接库中。由此可见DLL对我们来说并不陌生。

静态LIB库:这种提供形式通常包含LIB库文件、头文件及相关文档说明。
动态DLL库:这种提供形式也包含LIB库文件(有些厂商不提供LIB库文件),头文件,DLL文件以及相关文档说明。通常都是通过(LoadLibrary->GetProcAddress方式载入DLL库)

动态连接库与静态连接库相同与区别

      动态连接库与静态连接库在编写和调用上的不同体现在库的外部接口定义及调用方式略有差异。静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中。但若使用DLL,该DLL不必被包含在最终EXE文件,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。
      静态链接库和动态链接库的另外一个区别在于:静态连接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。

编写调用静态链接库方式:

1.直接在代码前添加引号

#include “…/DLL/DLL.h”
#pragma comment(lib,"…/DLL/DLL1/lib") //添加库文件

2.在解决方案管理面板中添加头文件和资源文件

添加一个现有项头文件,在文件夹中找到第三方库的头文件(DLL.h),添加进新建立的项目。
添加一个现有项资源文件,在文件夹中找到第三方库的库文件(DLL1.lib),添加进新建立的项目,

3.在项目属性设置中添加头文件和库文件

项目->属性->VC++目录->包含目录中添加第三方的头文件:库目录下添加i第三方库的库文件(.lib文件)
项目->属性->链接器->输入->附加依赖项中输入库文件名称

编写方式:
      在VC++6.0中new一个libTest的static library工程,并新建lib.h和lib.cpp两个文件,lib.h和lib.cpp的源代码:

DEMO:
lib.h
#ifdef LIB_H
#define LIB_H
extern "C" int add(int x,int y);	//生命为C编程、链接方式的外部函数
#endif
DEMO:
lib.cpp
#include "lib.h"
int add(int x,int y)
{
    
    
	return x+y;
}

      编译这个工程就得到一个.lib文件,这个文件就是一个函数库,它提供了add的功能。将头文件和.lib文件提供给用户后,用户可以直接使用其中的add函数。

标准TurboC2.0中的C库函数(scanf、printf、memcpy、strcpy)就来自这种静态库。//了解

      如何使用这个库,在libTest工程所在的工作区内new一个libCall工程,libCall工程仅包含一个main.cpp文件,演示了静态连接库的调用方法。

#icnlude <stdio.h>
#include "../lib.h"
#pragma comment(lib,"..//debug//libTest.lib")	//指定与静态库一起连接
int main(int argc,char* argv[])
{
    
    
	printf("2 + 3 = %d",add(2,3));
}

代码中#pragma comment(lib,"…//debug//libTest.lib")的意思是指本文件生成的.obj文件应与libTest.lib一起连接。
#pragma comment指定库路径。

工具: Depends

      对于喜欢调试和逆向的同仁推荐一个工具:Depends.
      Depends工具可以显示DLL的层次结构,若用它打开一个可执行文件则可以看出这个可执行文件调用了哪些DLL.
      Dependency Walker是一个免费的使用程序,可扫描任何32位或64位windows模块(exe,dll,ocx,sys等),并构建所有从属模块的层次树状图。对于找到的每个模块,它列出了模块导出的所有功能,以及其他模块实际上正在调用的功能。另一个视图显示最少的必需文件集,以及有关每个文件的完整路径,基地址,版本号,计算机类型,调试信息等。

用途:
      Dependency Walker对解决与加载和执行模块有关的系统错误非常有用。
      可以作为图形应用程序或控制台应用程序运行。
      依赖项Walker处理所有类型的模块依赖项,包括隐式,显式(动态/运行时),转发,延迟加载和注入。

检测系统错误类型:
(缺少模块,无效模块,导入/导出不匹配,循环依赖项错误,模块的机器类型不匹配以及模块初始化失败)

下载地址:http://www.dependencywalker.com/
(需要修改2020.11.29做修改,周知)

猜你喜欢

转载自blog.csdn.net/qq_31932681/article/details/110046098