什么是DLL:
自从微软推出
16位的
Windows操作系统起,此后每种版本的
Windows操作系统都非常依赖于动态链接库
(DLL)中的函数和数据,实际上
Windows操作系统中几乎所有的内容都由
DLL以一种或另外一种形式代表着,例如显示的字体和图标存储在
GDI DLL中、显示
Windows桌面和处理用户的输入所需要的代码被存储在一个
User DLL中、
Windows编程所需要的大量的
API函数也被包含在
Kernel DLL中。
DLL是建立在客户
/服务器通信的概念上,包含若干函数、类或资源的库文件,函数和数据被存储在一个
DLL(服务器)上并由一个或多个客户导出而使用,这些客户可以是应用程序或者是其它的
DLL。
DLL库不同于静态库,在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为
*.LIB),
Visual C++的编译器在处理程序代码时将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为
"静态链接
",此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。
在动态库的情况下,有两个文件,一个是引入库(
.LIB)文件,一个是
DLL文件,引入库文件包含被
DLL导出的函数的名称和位置,
DLL包含实际的函数和数据,应用程序使用
LIB文件链接到所需要使用的
DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是
DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,
DLL和
.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。
微软的
Visual C++支持三种
DLL,它们分别是
Non-MFC Dll(非
MFC动态库)、
Regular Dll(常规
DLL)、
Extension Dll(扩展
DLL)。
Non-MFC DLL指的是不用
MFC的类库结构,直接用
C语言写的
DLL,其导出的函数是标准的
C接口,能被非
MFC或
MFC编写的应用程序所调用。
Regular DLL:和下述的
Extension Dlls一样,是用
MFC类库编写的,它的一个明显的特点是在源文件里有一个继承
CWinApp的类(注意:此类
DLL虽然从
CWinApp派生,但没有消息循环)
,被导出的函数是
C函数、
C++类或者
C++成员函数(注意不要把术语
C++类与
MFC的微软基础
C++类相混淆),调用常规
DLL的应用程序不必是
MFC应用程序,只要是能调用类
C函数的应用程序就可以,它们可以是在
Visual C++、
Dephi、
Visual Basic、
Borland C等编译环境下利用
DLL开发应用程序。
DLL的创建:
打开VS2013,选择Win32:
选择DLL:
里边会自动为你添加好几个文件:
以及一个dllmain的格式,这里面是,当加载一个DLL(ATTACH)或者释放一个DLL(DETACH)等不同状态发生时,所要执行的代码(只不过下面的代码是当四个状态发生时什么都不执行):
参数中,
hMoudle是动态库被调用时所传递来的一个指向自己的句柄
(实际上,它是指向
_DGROUP段的一个选择符
);
ul_reason_for_call是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:
DLL_PROCESS_ATTACH: 进程被调用、
DLL_THREAD_ATTACH: 线程被调用、
DLL_PROCESS_DETACH: 进程被停止、
DLL_THREAD_DETACH: 线程被停止;
lpReserved为保留参数。
我们直接在testDLL.cpp中添加代码,这里保存的是DLL的导出函数:
extern "C" __declspec(dllexport) int add(int a, int b)
return (a + b);
extern "C" __declspec(dllexport) int sub(int a, int b)
return (a - b);
编译生成一个testDLL.dll.下面进行测试:
隐式连接:
#include <iostream>
#include <windows.h>
#pragma comment(lib,"testDLL.lib")
extern "C"_declspec(dllimport) int add(int a, int b);
extern "C"_declspec(dllimport) int sub(int a, int b);
int main()
int nParam1 = 9;
int nParam2 = 3;
int nAdd = add(nParam1, nParam2);
int nSub = sub(nParam1, nParam2);
std::cout << nAdd << ":" << nSub << std::endl;
system("pause");
return 0;
显示链接:
#include <iostream>
#include <windows.h>
int main()
typedef int (*_pAdd)(int a, int b);
typedef int (*_pSub)(int a, int b);
HINSTANCE hDll = LoadLibrary("testDLL.dll");
int nParam1 = 9;
int nParam2 = 3;
_pAdd pAdd = (_pAdd)GetProcAddress(hDll, "add");
_pSub pSub = (_pSub)GetProcAddress(hDll, "sub");
int nAdd = pAdd(nParam1, nParam2);
int nSub = pSub(nParam1, nParam2);
std::cout << nAdd << ":" << nSub << std::endl;
FreeLibrary(hDll);
system("pause");
return 0;
正确输出结果:
http://www.cnblogs.com/daocaoren/archive/2012/05/30/2526495.html