动态链接库
n 动态链接库通常不能直接运行,也不能接受消息。他们是一些独立的文件,其中包含能被可执行程序或其他DLL调用来完成某项工作的函数。只有在其他模块调用动态链接库中的函数时,它才发挥作用。
n Windows API中的所用函数都是包含在DLL中。其中有3个最重要的DLL, Kernel32.dll,它包含用于管理内存、进程和线程的各个函数;User32.dll,它包含用于执行用户界面任务(如窗体的创建和消息的传递)的各个函数。
n 静态库:函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下,编译链接可执行文件时,链接器从库中复制这些函数和数据并把他们和应用程序的其他模块组合起来创建最终的可执行文件(.EXE文件)。
n 动态库:在使用动态库的时候,往往提供两个文件:一个引入库和一个DLL。引入库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。在编译链接可执行文件时,只需要链接引入库,DLL中的函数代码和数据并不复制到可执行文件中,在运行的时候,再去加载DLL,访问DLL中的导出函数。
n 使用动态链接库的好处:
1. 可以采用多种编程语言来编写。
2. 增强产品的功能。
3. 提供二次开发的平台。
4. 简化项目管理。
5. 可以节省磁盘空间和内存。
6. 有助于资源的共享。
7. 有助于实现应用程序的本地化
n 引入方式:
1. 隐式引入(直接在项目设置里链接选项卡里导入.LIB的引入文件)
2. 显示引入(使用LoadLibrary、GetProcAddress、FreeLibrary)
n 导出声明
使用模版定义文件(.def)
作用:禁用名字改编但类不能禁用,类的方法却可以禁用,但调用约定也要保持一致。
LIBRARY “Dll1”
EXPORTS
add
subtract
n 在客服端的使用
在源文件中声明的方式:
1. Extern int add(int a, int b);
Extern int subtract(int a, int b);
推荐(更快)
2. _declspec(import) int add(int a, int b);
_declspec(import) int subtract(int a, int b);
在头文件中的声明的方式:
Dll1.h
#ifndefDLL1_API
#defineDLL1_API extern “C”_declspec(dllimport)
#endif
DLL1_APIint add(int a,int b);
DLL1_APIint subtract(int a,int b);
Dll.cpp
#defineDLL1_API extern “C”_declspec(dllexport)
#include"DLL1.h" //包含定义的头文件-Dll1.h
注:extern “C”使函数不参加名字改编但是不能导出类只能全局函数。如果函数的调用约定发生改变也将参加名字改编比如将默认的c语言调用约定改为了pascal调用约定时。
n 实例
为了演示建立动态链接库的一个过程,在此实例中只完成在动态链接库中建立一个类和两个函数。
Step1.新建一个空的动态链接库工程。
Step2.添加一个头文件(Dll3.h)录入如下代码:
#ifndefDLL3_API
#defineDLL3_API_declspec(dllimport)
#endif
DLL3_APIint add(int,int);
DLL3_APIint subtract(int,int);
class DLL3_API MyRectangle
{
public:
MyRectangle(int,int);
int GetArea();
private:
int width_;
int height_;
};
Step3.添加一个原文件(Dll3.cpp)录入如下代码:
#defineDLL3_API_declspec(dllexport)
#include"Dll3.h"
int add(int a,int b)
{
return a + b;
}
int subtract(int a,int b)
{
return a - b;
}
MyRectangle::MyRectangle(int w, int h):width_(w), height_(h){}
int MyRectangle::GetArea()
{
return width_ * height_;
}
Step4.添加一个模版定义文件(Dll3.def)录入如下代码:
在当前目录下建立一个文本文件更名为Dll3.def再导入到工程中即可
LIBRARY "Dll3"
EXPORTS
add
subtract
GetArea
Step5.编译工程。
Step6.建立一个测试动态链接库的对话框工程(DllTest)
Step7.在对话框中添加三个按钮测试动态链接库的函数(库以隐式引入)
Step8.把动态链接库工程Debug目录下的Dll3.dll和Dll3.lib以及Dll3.h文件要不然编译器会找不到你需要的函数和函数的声明。
Step9.导入Dll3.h头文件
#include ”Dll3.h”
Step10.添加按钮的单击处理事件(双击当前按钮即可)
void CTestDllDlg::OnBtnAdd()
{
CString result;
result.Format("3 + 5 = %d", add(3, 5));
MessageBox(result);
//下面是库以显示方式调用,如果使用显示方式就不需要隐式的导入库也不需要Dll3.h头文件,因为显示方式是在程序运行后单击按钮才加载的并获取了函数的地址,所以可以直接调用。
/*HINSTANCE hinst;
hinst = LoadLibrary("Dll3.dll");
typedef int (*FARProc)(int a, int b);
FARProc proc;
proc = (FARProc)GetProcAddress(hinst, "add");
if(!proc)
{
MessageBox("没有找到函数地址");
return;
}
CString result;
result.Format("3 + 5 = %d", (*proc)(3, 5));
MessageBox(result);
FreeLibrary(hinst);
*/
}
void CTestDllDlg::OnBtnSubtract()
{
CString result;
result.Format("5 - 3 = %d", subtract(5, 3));
MessageBox(result);
}
void CTestDllDlg::OnBtnClass()
{
MyRectangle rect(10, 5);
CString result;
result.Format("W:10 H:5 A=%d", rect.GetArea());
MessageBox(result);
}
Step10.测试
声明:此文档是由孙鑫老师教学视频整理,需要更详细的学习动态链接库的相关知识可以在百度上搜索“孙鑫VC++视频”共20集非常不错的VC++教学视频。