DLL(动态链接库)编程

原创 2007年09月13日 13:25:00

dll是现在常见的文件,它集成了程序的很多功能在里面。一般情况下,它不能直接被执行,常见的使用方法是用其他的*.exe调用其执行,以使其内部功能表现出来。还有*.ocx文件也与之类似,也就是人们常说的com
1.简要
         Windows API中所有的函数都包含在dll中,其中有3个最重要的DLL
        (1)   Kernel32.dll
        它包含那些用于管理内存、进程和线程的函数,例如CreateThread函数;
        (2)   User32.dll
       它包含那些用于执行用户界面任务(如窗口的创建和消息的传送)的函数,例如CreateWindow函数;
        (3)   GDI32.dll
       它包含那些用于画图和显示文本的函数。
2.      静态库和动态库
(1)   静态库
           函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.Exe文件).当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。(2)   动态库
        在使用动态库的时候,往往提供两个文件:一个引入库(.lib)文件和一个DLL(.dll)文件。虽然引入库的后缀名也是”lib”,但是动态库的引入库文件和静态库文件有着本质上的区别,对一个DLL来说,其引入库文件(.lib)包含该DLL导出的函数和变量的符号名,而.dll文件包含该DLL实际的函数和数据。在使用动态库的情况下,在编译链接可执行文件时,只需要链接该DLL的引入库文件,该DLL中的函数代码和数据并不复制到可执行文件中,直到可执行程序运行时,才去加载所需的DLL,将该DLL映射到进程的地址空间外,然后访问DLL中导出的函数。这时,发布产品时,除了发布可执行文件以外,同时还要发布该程序将要调用的动态链接库。
3.      在导出库头文件中的标准写法:
#ifdef LIBDAQ_EXPORTS
#define LIBDAQ_API __declspec(dllexport)
#else
#define LIBDAQ_API __declspec(dllimport)
#endif
     将该头文件添加到某客户代码中时,会自动展开。如果客户代码没有定义LIBDAQ_EXPORTS,那么LIBDAQ_EXPORTS会被定义为__declspec(dllimport)表示有LIBDAQ_EXPORTS头的函数都是从该DLL中导入的。
4.      名字改编和”extern “C””
           C++编译器在生成DLL时,会对导出的函数进行名字改编,并且不同的编译器使用的改变规则不一样,因此改编后的名字会不一样。这样,如果利用不同的编译器分别生成DLL和访问该DLL的客户端代码程序的话,后者在访问该DLL的导出函数时会出现问题。为了实现通用性,需要加上限定符:extern “C”
           但是利用限定符extern “C”可以解决C++C之间相互调用时函数命名的问题,但是这种方法有一个缺陷,就是不能用于导出一个类的成员函数,只能用于导出全局函数。
5.      显示加载方式加载DLL
           使用动态方式来加载动态链接库时,需要用到LoadLibrary函数。该函数的作用就是将指定的可执行模块映射到调用进程的地址空间。调用原型为:
HMODULE LoadLibrary(LPCTSTR lpFileName);
           LoadLibrary函数不仅可以加载DLL,还可以加载可执行模块(Exe)。当加载可执行模块时,主要是为了访问该模块内的一些资源,例如对话框资源、位图资源或图标资源等。LoadLibrary函数有一个字符串类型(LPCTSTR)的参数,该参数指定了可执行模块的名称,既可以是一个dll文件,也可以是一个exe文件。如果调用成功,LoadLibrary函数将返回所加载的那个模块的句柄。返回类型HMODULEHINSTANCE可以通用。
           当加载到动态链接库模块的句柄后,接下来就要想办法获取该动态链接库中导出函数的地址,这可以通过调用GetProcAddress函数来实现。该函数用来获取DLL导出函数的地址,其原型声明如下所示:
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
参数hModule:指定动态链接库模块的句柄,即LoadLibrary函数的返回值。
参数lpProcName:一个指向常量的字符指针,指定DLL导出函数的名字或函数的序号。如果是序号,则序号必须在低位字节中,高位字节必须是0
如果调用成功,GetProcAddress函数将返回指定导出函数的地址;否则返回NULL
例如:
HINSTANCE hInst;
hInst = LoadLibrary(“DllTest.dll”);
typedef int (*ADDPROC)(int a, int b);
ADDPROC add = (ADDPROC)GetProcAddress(hInst, “add”);
if (!add)
print(“Failure”);
else
process next events
FreeLibrary(hInst);
调用语法:
BOOL FreeLibrary(HMODULE hModule);
6.      加载DLL的两种方式优缺点:
       采用动态加载方式,那么可以在需要时才加载DLL,而隐式链接方式实现起来比较简单,在编写客户端代码时就可以把链接工作做好,在程序中可以随时调用DLL导出的函数。但是如果程序需要访问十多个DLL时,如果都采用隐式链接方式加载它们的话,那么在该程序启动时,这些DLL都需要被加载到内存中,并映射到调用进程的地址空间,这样将加大程序的启动时间。而且一般来说,在程序运行过程中只是在某个条件满足时才需要访问某个DLL中的某个函数,其它情况下都不需要访问这些DLL中的函数。但是这时所有的DLL都已经被加载到内存中,资源浪费是比较严重的。这个时候就需要采用显示加载的方式来访问DLL,在需要时才加载所需的DLL。也就是说在需要时才被加载到内存中,并被映射到调用进程的地址控件中。需要说明的是,隐式链接方式访问DLL时,在程序启动时也是通过LoadLibrary函数加载该进程需要的动态链接库的。
7.      DllMain函数
           如果提供了DllMain函数(该函数是可以选择存在的),那么在此函数中不要进行太复杂的调用。因为在加载该动态链接库时,可能还有一些核心动态链接库没有被加载。例如Use32.dllGDI32.dll。我们自己编写的DLL会比较靠前地被加载。

 

VC++动态链接库(DLL)编程深入浅出系列

VC++动态链接库(DLL)编程深入浅出(一)http://www.pconline.com.cn/pcedu/empolder/gj/vc/0509/698632.htmlVC++动态链接库(DLL...
  • daichanglin
  • daichanglin
  • 2006年11月15日 15:43
  • 974

Windows下的VC++动态链接库编程

VC++动态链接库编程 1、基础概念 1.1 链接库的概述 动态链接库DLL(DynamicLinkable Library),你可以简单的把它看成一种仓库,它提供给你一些可以直接拿来用的变量、...
  • inrgihc
  • inrgihc
  • 2015年10月20日 21:31
  • 2086

动态链接库的初步学习

动态链接库DLL还是比较常用的,之前一直不理解,这几天因为要用学了一下,算是入了一下门吧。现把学习过程记录一下,供参考。 动态链接库的初步学习...
  • NNNNNNNNNNNNY
  • NNNNNNNNNNNNY
  • 2015年09月22日 21:56
  • 1259

DLL动态链接库编程入门之三:MFC规则DLL(上)

上一节中讲解了非MFC DLL,本节将介绍如何创建MFC规则DLL及使用MFC规则DLL的方法。    一、MFC规则DLL概述   MFC规则DLL的概念体现在两方面:   (1)...
  • misasagi_inori
  • misasagi_inori
  • 2013年09月12日 22:12
  • 1067

DLL动态链接库 总结 看了孙鑫老师的书和笔记 自己做了下 小做总结

DLL动态链接库 总结 看了孙鑫老师的书和笔记 自己做了下 小做总结 DLL  动态库,静态库。动态库节约磁盘空间,静态库体积大。(不是很清楚) 两种加载方式:隐式调用、动态加载。 ...
  • newmanlf
  • newmanlf
  • 2012年01月31日 14:47
  • 1628

【VC++DLL动态链接库编程】VC++静态库编译(3)

创建一个静态库,得有一个程序去调用它, 首先添加一个类:菜单栏: 项目-->添加类-->C++类 在staticLib右击属性, 新建一个项目: 静态库的引用:除了项目设置中的属性进行引...
  • SMF0504
  • SMF0504
  • 2017年01月22日 15:18
  • 596

动态链接库开发说明

目 录 第1章 基本概念    1 1.1 一个简单的例子    1 1.1.1 新建一个VC++项目    1 1.1.2 添加源文件    3...
  • Hanford
  • Hanford
  • 2016年12月14日 09:05
  • 798

动态链接库DLL的通俗理解

今天主要布置了一个任务要求写一个ocx控件,是用VC开发,虽然一直以来都是用VC写程序,但是使用到的功能仅仅是写一个小程编译运行,连链接都省去了,因为所有的功能都在一个文件里面就省去了链接这一步,所以...
  • u012247462
  • u012247462
  • 2015年01月04日 21:07
  • 1784

vs2013创建和使用动态链接库

本文将创建一个简单的动态链接库,并编写一个应用台控制程序使用该动态链接库,并提出了与实现相关的几个问题,供初学者交流。 本文包含以下内容: 创建动态链接库项目 向动态链接库添加类 ...
  • qinzhenhua100
  • qinzhenhua100
  • 2017年03月19日 21:08
  • 637

用VS2010将C程序做成动态链接库dll

/* 一直在做linux编程,突然要移植到windows,摸索了好久,记录下,分三篇来记录: 1.用vs2010将C做成dll 2.c#做界面后,如何调用C语言函数/dll 3.c#程序的打包...
  • leo9150285
  • leo9150285
  • 2013年04月16日 13:41
  • 5645
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DLL(动态链接库)编程
举报原因:
原因补充:

(最多只允许输入30个字)