我的微信公众平台:AIT111666888
动态链接库通常都不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其它DLL调用来完成某项工作的函数。只有在其它模块调用动态链接库中的函数时,它才发挥作用。
Windows API中的所有函数都包含在DLL中。其中有3个最重要的DLL,Kernel32.dll,它包含用于管理内存、进程和线程的各个函数;User32.dll,它包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数;GDI32.dll,它包含用于画图和显示文本的各个函数。
静态库:函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文件(.EXE文件)。
在使用动态库的时候,往往提供两个文件:一个引入库和一个DLL。引入库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。在编译链接可执行文件时,只需要链接引入库,DLL中的函数代码和数据并不复制到可执行文件中,在运行的时候,再去加载DLL,访问DLL中导出的函数。
使用动态链接库的好处
可以采用多种编程语言来编写。
增强产品的功能。
提供二次开发的平台。
简化项目管理。
可以节省磁盘空间和内存。
有助于资源的共享。
有助于实现应用程序的本地化。
动态链接库加载的两种方式
隐式链接
显示加载
vs2012
第一步
第二步
第三步
在空白的文件中写入下列代码
int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; }
然后编译在Dll1目录下的debug文件夹下会生成Dll1.dll文件
有了Dll1.dll文件,其他的.cpp文件还不能去访问动态链接库里面的函数,如果其他的程序想要使用动态链接库里的函数,那么这些函数必须是导出的函数。
查看动态链接库中哪些函数是被导出的 的方法
D:\vs2012\VC\bin 这个路径是你安装vs2012的路径 这个路径下有一个dumbin.exe文件
首先将D:\vs2012\VC\bin下的vcvars32.bat文件拖拽到 命令提示符里面
然后按照下面的方法输入 输入的目录是你Dll1.dll文件所在的目录
接着按照下面的输入红框中的内容
蓝框中显示没有导出函数
修改代码按照下面
_declspec(dllexport) int add(int a, int b) { return a + b; } _declspec(dllexport) int subtract(int a, int b) { return a - b; }
_declspec是关键字,作用将函数变为导出函数。
再次使用dumpbin,我们会看到导出函数,显示在蓝框中
下面去编写测试程序来调用动态链接库
第一步
创建MFC程序,命名为DllTest
选择基于对话框的程序
创建两个按钮
Add id IDC_BTN_ADD
Subtract id IDC_BTN_SUBTRACT
双击两个控件会产生两个消息响应函数
extern int add(int a, int b);
extern int subtract(int a, int b);
void CDllTestDlg::OnBnClickedBtnAdd()
{
// TODO: 在此添加控件通知处理程序代码
}
void CDllTestDlg::OnBnClickedBtnSubtract()
{
// TODO: 在此添加控件通知处理程序代码
}
在这两个函数中我们分别调用动态链接库中的add函数和subtract函数
在调用之前我们要声明一下,表明这两个函数是在外部定义的函数
完整代码
extern int add(int a, int b); extern int subtract(int a, int b); void CDllTestDlg::OnBnClickedBtnAdd() { // TODO: 在此添加控件通知处理程序代码 CString str; str.Format(_T("5+3=%d"), add(5, 3)); MessageBox(str); } void CDllTestDlg::OnBnClickedBtnSubtract() { // TODO: 在此添加控件通知处理程序代码 CString str; str.Format(_T("5-3=%d"), subtract(5, 3)); MessageBox(str); }
编译会出现下面的错误
1>DllTestDlg.obj : error LNK2019: 无法解析的外部符号 "int __cdecl add(int,int)" (?add@@YAHHH@Z),该符号在函数 "public: void __thiscall CDllTestDlg::OnBnClickedBtnAdd(void)" (?OnBnClickedBtnAdd@CDllTestDlg@@QAEXXZ) 中被引用 1>DllTestDlg.obj : error LNK2019: 无法解析的外部符号 "int __cdecl subtract(int,int)" (?subtract@@YAHHH@Z),该符号在函数 "public: void __thiscall CDllTestDlg::OnBnClickedBtnSubtract(void)" (?OnBnClickedBtnSubtract@CDllTestDlg@@QAEXXZ) 中被引用
解决方法
K:\c++\Dll1\Debug是之前生成Dll1.lib的路径
然后再编译会出现下面的问题
解决办法
将之前生成的Dll1.dll文件拷贝到当前工程的Debug目录下
重新编译执行
以上内容参考孙鑫老师的MFC视频