动态链接库加载的两种方法

动态链接库加载的两种方法

1.隐式链接
2.显示加载

一.隐式链接

创建Win32 Dynamic-Link Library程序Dll1

Dll1.cpp文件

  1. #define DLL1_API extern "C" _declspec(dllexport)//用了extern "C"就不能导出类了,只能导出全局函数  
  2. #include "Dll1.h"  
  3. #include <windows.h>  
  4. #include <stdio.h>  
  5.   
  6. int add(int a, int b)  
  7. {  
  8.     return a+b;  
  9. }  
  10.   
  11. int subtract(int a, int b)  
  12. {  
  13.     return a-b;  
  14. }  
  15.   
  16. /*void Point::output(int x, int y) 
  17. { 
  18.     //该函数在调用者窗体上输出x与y的值 
  19.     HWND hwnd = GetForegroundWindow();//获取客户当前调用窗口的句柄 
  20.     HDC hdc = GetDC(hwnd); 
  21.     char buf[20]; 
  22.     memset(buf,0,20); 
  23.     sprintf(buf,"x=%d,y=%d",x,y); 
  24.     TextOut(hdc, 0, 0, buf, strlen(buf)); 
  25.     ReleaseDC(hwnd, hdc); 
  26. }*/  

Dll1.h文件

  1. #ifdef DLL1_API  
  2. #else  
  3. // 此处extern "C"是给客户端使用的表明导出的函数名字不改变  
  4. //如果不加extern "C",C++会按照它的规则改变函数名字,那样用C写的客户端就找不到该函数了  
  5. //但是,加上extern "C"只能导出全局函数了 所以注释了导出类  
  6. #define DLL1_API extern "C" _declspec(dllimport)  
  7. #endif  
  8.   
  9. /*_stdcall表示为标准调用约定。如果不加_stdcall函数为C调用约定。delphi就为_stdcall(标准调用约定). 
  10. 但用_stdcall声明后,函数名会改变,如何导出原函数名请看第二节。二.显示加载(动态链接) 
  11. DLL1_API int _stdcall add(int a, int b); 
  12. DLL1_API int _stdcall subtract(int a, int b);*/  
  13. DLL1_API int add(int a, int b);  
  14. DLL1_API int subtract(int a, int b);  
  15. //在类名前加上_declspec(dllimport)声明,可以导出类/*class DLL1_API Point{public:void output(int x, int y);};*///如果不想导出整个类只需在类的成员函数前面加上_declspec(dllexport)声明(但访问权限必须是public)。//此头文件应写成/*class Point{public:DLL1_API void output(int x, int y);void test();};*//*此头文件既可以给dll源文件使用也可以给调用dll的客户端程序使用。dll源文件使用时,在Dll1.cpp文件中定义#define DLL1_API _declspec(dllexport),表示为导出。在客户端程序调用时,定义#define DLL1_API _declspec(dllimport),表示导入*/  
  1. <pre name="code" class="html"><pre></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <pre></pre>  
  6. <pre></pre>  
  7. <pre></pre>  
  8. <pre></pre>  
  9. <pre></pre>  
  10. <pre></pre>  
  11. <pre></pre>  
  12. </pre>  

Dll1.dll测试如下:

1.建立MFC AppWizard(exe)测试程序Test。
2.编译Dll1程序成功后,会生成Dll1.dll文件和Dll1.lib文件,把Dll1.dll文件和Dll1.lib文件复制到测试文件下。
3.Test程序中,点击Project->seeting->Link  在Object/library modules:下把.lib文件名写上。此时为Dll1.lib
4.在Test程序的Dialog上添加两个按钮。响应函数分别如下
  1. void CTestDlg::OnBtnadd()   
  2. {  
  3.     // TODO: Add your control notification handler code here  
  4.     CString str;  
  5.     str.Format("5+3=%d", add(5,3));  
  6.     MessageBox(str);  
  7. }  
  8.   
  9. void CTestDlg::OnBtnsubtract()   
  10. {  
  11.     // TODO: Add your control notification handler code here  
  12.     CString str;  
  13.     str.Format("5-3=%d", subtract(5,3));  
  14.     MessageBox(str);  
  15. }  
5.别忘记在Test的源程序里调用Dll1.h,此头文件声明了从dll中导入的函数。

二.显示加载(动态链接)

创建Win32 Dynamic-Link Library程序Dll2
Dll2.cpp文件
  1. //_stdcall为标准调用约定。因为有def文件所以导出函数不会改变名字  
  2. int _stdcall add(int a, int b)  
  3. {  
  4.     return a+b;  
  5. }  
  6.   
  7. int _stdcall substract(int a,int b)  
  8. {  
  9.     return a-b;  
  10. }  

在Dll2工程文件夹内建立Dll2.def文件
  1. LIBRARY Dll2  
  2.   
  3. EXPORTS  
  4. add  
  5. substract  

测试Dll2.dll如下:
1.把Dll2.dll文件复制到Test程序文件夹下
2.按钮响应函数如下
  1. //动态加载不需要.lib与头文件。只需要DLL文件  
  2.     HINSTANCE hInst;  
  3.     hInst = LoadLibrary("Dll2.dll");//加载动态链接库  
  4.     typedef int (_stdcall *ADDPROC)(int a, int b);//定义函数指针类型,用来接收函数地址  
  5.     //获取指定导出的动态链接库的地址  
  6. //  ADDPROC Add = (ADDPROC)GetProcAddress(hInst, "add");//通过函数名调用动态链接库导出的函数(首选,能保证不出错)  
  7.     ADDPROC Add = (ADDPROC)GetProcAddress(hInst, MAKEINTRESOURCE(1));//通过序号调用动态链接库导出的函数  
  8.     if (!Add)  
  9.     {  
  10.         MessageBox("获取函数地址失败!");  
  11.     }  
  12.     CString str;  
  13.     str.Format("5+3=%d", Add(5,3));  
  14.     MessageBox(str);  
  15.     FreeLibrary(hInst);//减少加载动态链接库的引用计数。释放动态链接库  

注:查看动态链接库导出的函数可用dumpbin命令。 在cmd中进入到该dll目录,(如该dll名称为dll1.dll)敲入命令:
dumpbin -exports dll1.dll

注:查看可执行程序(.exe程序)导入的函数可用dumpbin命令。 在cmd中进入到该exe程序目录,(如该exe名称为test.exe)敲入命令: dumpbin -imports test.exe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值