VC2008如何生成及使用DLL(完整版)

生成、使用DLL看起来简单,但做起来才发现还是有一些地方需要注意的。

1. 打开VS2008,新建一个VC工程,选择Win32类型,Win32项目:

建立VC Win32工程


2. 应用程序类型选择DLL,附加选项选择到处符号,公共头文件不要选择,然后点完成即可。

3. 工程生成后需要修改属性,在配置属性的常规选项中将MFC的使用修改为“静态库中使用MFC”。

   注意,这一步是必须的,否则写出来的DLL将需要在有VC2008的环境上才能运行。

4. 关注自动生成的文件MyDllTest.cpp,其中有几个实例,可以将他们删除,也可以不管他们。

5. 添加自己的接口,如:GetMyDllVersion


・・・・・・・・・10・・・・・・・・20・・・・・・・・30・・・・・・・・40・・・・・・・・50・・・・・・・・60・・・・・・・・70・・・・・・・・80・・・・・・・・90・・・・・・・・100・・・・・・・110・・・・・・・120・・・・・・・130・・・・・・・140・・・・・・・150
  1. // 得到当前DLL的版本号

  2. MYDLLTEST_API UINT32  GetMyDllVerion( VOID )  

  3. {  

  4. return  1234;  

  5. }  

6. 在头文件MyDllTest.h中添加声明


・・・・・・・・・10・・・・・・・・20・・・・・・・・30・・・・・・・・40・・・・・・・・50・・・・・・・・60・・・・・・・・70・・・・・・・・80・・・・・・・・90・・・・・・・・100・・・・・・・110・・・・・・・120・・・・・・・130・・・・・・・140・・・・・・・150
  1. MYDLLTEST_API  UINT32  GetMyDllVerion( VOID );  

7. 添加导出符号定义文件,理论上是可以不要导出定义的,但是那样的结果就是生成的DLL中的符号名字不明确,只有定义了导出符号,才可以使得DLL中的借口函数名称得以确定。(关于def与dll 请参阅msdn )

文件内容:
・・・・・・・・・10・・・・・・・・20・・・・・・・・30・・・・・・・・40・・・・・・・・50・・・・・・・・60・・・・・・・・70・・・・・・・・80・・・・・・・・90・・・・・・・・100・・・・・・・110・・・・・・・120・・・・・・・130・・・・・・・140・・・・・・・150
  1. LIBRARY  "MyDllTest"

  2. EXPORTS  

  3. GetMyDllVerion  

8. 在项目属性中设置模块定义文件为刚才建立的symexport.def文件:

设置DLL的输出符号定义文件

9. 生成,可以得到一个MyDllTest.dll,使用Depends工具(VC6.0自带)可以查看这个DLL中包含了多少接口以及接口名:

使用Depends工具查看DLL接口

会发现除了我们定义的借口GetMyDllVersion外还有几个??开头的接口,他们就是那些没有在模块定义文件中定义的借口自动生成的。

10. 除了DLL外我们还会发现生成了MyDllTest.lib文件,这个lib文件可以在其他的程序使用这个DLL的时候将其连接进去,同时只要包含MyDllTest.h即可调用这个DLL中的借口了。


如何引入dll

方法一.装载期间动态加载。(需要lib和dll)

  1。新建Win32应用程序空项目。

  2。把生成的dll、lib这2个文件复制到新建的目录下。

  3。添加导入库:工具--项目和解决方案(vs里是options)--VC++目录,选择右侧“显示以下内容的目录”下的“库文件”,把lib所在目录添加。

  4。头文件: MyDllTest.h(与编写DLL中一样)

  5。源文件:main.c


可注释#pragma comment(lib," MyDllTest.lib")这条,但必须设置链接库,方法:

  右击项目--属性--配置属性--链接器--输入--附加依赖项: MyDllTest.lib


  1. #include "MyDllTest.h"

  2. #include "windows.h"

  3. #pragma comment(lib,"MyDllTest.lib")

  4. int  WINAPI WinMain(__in  HINSTANCE  hInstance, __in_opt  HINSTANCE  hPrevInstance, __in_opt  LPSTR  lpCmdLine, __in  int  nShowCmd )  

  5. {  

  6. GetMyDllVersion();  

  7. return  0;  

  8. }  

方法二:运行期间动态加载。(只需Dll文件即可)

需要使用 Windows API 函数: LoadLibraryGetProcAddress 以及 FreeLibrary



#include <iostream>

#include <windows.h>
using namespace std;
//定义FunctionFunc为指向一个返回值为int型 无参数的函数的指针
typedef int (*FunctionFunc)();

int main()
{
  FunctionFunc _FunctionFunc;
  //加载目标Dll
  HMODULE hModule = ::LoadLibrary (TEXT("D:\MyDllTest.dll"));
  if (hModule==NULL)//如果Dll加载失败,释放它占用的资源
  {
   ::FreeLibrary(hModule);
  }
  //取得目标Dll中导出函数的地址(提醒:函数名就是函数的入口地址)
  _FunctionFunc=(FunctionFunc)::GetProcAddress (hModule,"GetMyDllVersion");
  if (_FunctionFunc==NULL)
  {
   ::FreeLibrary (hModule);
  }
  int a =_FunctionFunc();
  cout<< a<<endl;
  ::FreeLibrary(hModule);
  cin.get();
  return 1;

}



 有时候我们拿到的是别人的DLL和头文件,但是却没有LIB文件,这时就要使用另外的方法调用DLL中的接口了,例如MD5接口的使用:


・・・・・・・・・10・・・・・・・・20・・・・・・・・30・・・・・・・・40・・・・・・・・50・・・・・・・・60・・・・・・・・70・・・・・・・・80・・・・・・・・90・・・・・・・・100・・・・・・・110・・・・・・・120・・・・・・・130・・・・・・・140・・・・・・・150
  1. // 按照MSDN中的说明定义函数原型如下

  2. typedefstruct

  3. {  

  4. ULONG  i[2];  

  5. ULONG  buf[4];  

  6.    unsigned char  in[64];  

  7.    unsigned char  digest[16];  

  8. } MD5_CTX;  

  9. typedefvoid  (CALLBACK* MD5Init_Tpye)(MD5_CTX* context);  

  10. typedefvoid  (CALLBACK* MD5Update_Tpye)(MD5_CTX* context,  

  11.                                        unsigned char * input,  

  12.                                        unsigned int  inlen);  

  13. typedefvoid  (CALLBACK* MD5Final_Tpye)(MD5_CTX* context);  




・・・・・・・・・10・・・・・・・・20・・・・・・・・30・・・・・・・・40・・・・・・・・50・・・・・・・・60・・・・・・・・70・・・・・・・・80・・・・・・・・90・・・・・・・・100・・・・・・・110・・・・・・・120・・・・・・・130・・・・・・・140・・・・・・・150
  1. // 使用MD5接口

  2. HINSTANCE  hDLL;  

  3. // MD5接口是在Cryptdll.dll中的

  4. hDLL = LoadLibrary(TEXT("Cryptdll.dll" ));  

  5. MD5Init_Tpye MD5Init;  

  6. MD5Update_Tpye MD5Update;  

  7. MD5Final_Tpye MD5Final;  

  8. // 得到接口指针

  9. MD5Init = (MD5Init_Tpye)GetProcAddress(hDLL, "MD5Init" );  

  10. MD5Update = (MD5Update_Tpye)GetProcAddress(hDLL, "MD5Update" );  

  11. MD5Final = (MD5Final_Tpye)GetProcAddress(hDLL, "MD5Final" );  

  12. if  (!MD5Init || !MD5Update || !MD5Final)  

  13. {  

  14. // 取得接口指针失败

  15.  FreeLibrary(hDLL);  

  16. return ;  

  17. }  

  18. MD5_CTX md5_context;  

  19. MD5Init(&md5_context);  

  20. MD5Update(&md5_context, src, length);  

  21. MD5Final(&md5_context);  

  22. // 不要忘记释放导入的DLL

  23. FreeLibrary(hDLL);  


这就是目前我知道的两种使用DLL的方法了,至于还有没有其他的方法,暂时没有这方面的需求,也就不去花脑力想了。。。


你可能感兴趣的:(dll)