动态链接库(Dynamic Link Library或者Dynamic-link library,缩写为DLL)
1. DLL是如何生成的?
DLL文件与EXE文件生成的过程基本一样, 在使用VS创建工程的时候,会遇到一个Application type选项,选择DLL选项后创建工程,编译这个工程就会生成DLL文件。创建的这个工程是不能独立运行的。
下面是一个DLL工程的代码示例:
DllHeader.h
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) void test(void);
extern "C" 的作用是,使用C编译的方法编译这个函数。
__declspec(dllexport)的作用是标识这个函数是需要导出的函数(即对外的接口)。
void test(void)是声明的函数。
DllTest.cpp
// DllTest.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "DllHeader.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
cout<<"Process attach."<<"\n";
break;
case DLL_PROCESS_DETACH:
cout<<"Process detach."<<"\n";
break;
case DLL_THREAD_ATTACH:
cout<<"Thread attach."<<"\n";
break;
case DLL_THREAD_DETACH:
cout<<"Thread detach."<<"\n";
break;
}
return TRUE;
}
void test(void)
{
cout<<":::::::::::::DLL has been called in this project!:::::::::::::"<<endl;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
1.1 DllMain函数
这个函数是工程创建的时候自动生成的函数,这个函数的第二个参数ul_reason_for_call指明了系统调用的DLL的原因。
他们分别是:
DLL_PROCESS_ATTACH
DLL_PROCESS_DETACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
百度百科中对DllMain的解释,链接地址:点击打开链接
1.2 test函数
这个函数是DllHeader.h文件中定义的函数的实体。
2.调用DLL的方法
2.1 动态调用
动态调用DLL是直接使用LocadLibrary和FreeLibrary函数进行。
请看下面的一段编码示例:
// ww.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
typedef int(*Dllfun)(void);
int _tmain(int argc, _TCHAR* argv[])
{
Dllfun test1;
HINSTANCE hdll;
// 载入指定的动态链接库,并将它映射到当前进程使用的地址空间。一旦载入,即可访问库内保存的资源
hdll = LoadLibraryA("C:\\Documents and Settings\\wanghe\\My Documents\\Visual Studio 2005\\Projects\\DllTest\\Debug\\DllTest.dll");
if (hdll == NULL)
{
FreeLibrary(hdll);
}
//vGetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址
test1 = (Dllfun)GetProcAddress(hdll, "test");
if (test1 == NULL)
{
FreeLibrary(hdll);
}
else
{
test1(); // 调用DLL中的函数
// 释放指定的动态链接库,它们早先是用LoadLibrary API函数装载的
FreeLibrary(hdll);
}
system("PAUSE");
return 0;
}
运行结果如下:
Process attach.
:::::::::::::DLL has been called in this project!:::::::::::::
Process detach.
Press any key to continue . . .
运行结果显示我们的工程成功调用了DLL中的test()函数
请注意LoadLibraryA/GetProcAddress/FreeLibrary这三个函数的使用方法。
这样动态调用DLL就完成了
2.2 静态调用
下面是静态引用的代码:
// ww.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
// 应用头文件(定义test函数的头文件)
#include "C:\\Documents and Settings\\wanghe\\My Documents\\Visual Studio 2005\\Projects\\DllTest\\DllTest\\DllHeader.h"
using namespace std;
#pragma comment(lib, "DllTest.lib") // 连接lib文件
int _tmain(int argc, _TCHAR* argv[])
{
test(); // 调用DLL中的函数
system("PAUSE");
return 0;
}
1) 应用头文件DllHeader.h
2)使用#pragma comment(lib, "DllTest.lib")
3)调用Dll中的函数test()