Windows动态链接库DLL[实践]

Windows动态链接库DLL[实践]
一直对动态链接库这个东西很陌生,今天刚好调试别人写的一个DLL项目,顺便就来研究一下下。
动态链接库的原理,好处那些就先不说了,直接来看怎么使用。
首先写一个动态链接库,其中 __declspec(dllexport)是用于MS编译器的一个关键字,用来将DLL中的内容导出而不需要.def文件了。
下面的cpp里就函数的定义了,DllMain函数跟普通的win32 console的main函数很像。
使用cl /c DLLImplement.cpp
link /dll DLLImplement.obj
就可以得到一个DLLImplement.dll顺便也会导出一个
DLLImplement. lib这个跟静态链接库很像的东西,实际上它的作用只是导出那些方法和变量的名字。

1  extern   " C "
2  {
3      __declspec(dllexport)  void  Set( int  i);
4      __declspec(dllexport)  int  Get();
5      __declspec(dllexport)  void  SayHello();
6 
7       int  value;
8  }
 1  #include  < iostream >
 2  #include  < objbase.h >
 3  #include  " DLLHeader.h "
 4 
 5 
 6  void  Set( int  i)
 7  {
 8      value  =  i;
 9  }
10  int  Get()
11  {
12       return  value;
13  }
14  void  SayHello()
15  {
16      std::cout << " Hello, I'm DLL, value is  " << value << std::endl;
17  }
18 
19 
20  BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason,  void *  lpReserved)
21  {
22      HANDLE g_hModule;
23 
24       switch (dwReason)
25      {
26       case  DLL_PROCESS_ATTACH:
27         std::cout << " DLL is attached! " << std::endl;
28         g_hModule  =  (HINSTANCE)hModule;
29          break ;
30 
31       case  DLL_PROCESS_DETACH:
32         std::cout << " DLL is detached! " << std::endl;
33         g_hModule = NULL;
34          break ;
35      }
36 
37       return  TRUE;
38  }
39 


使用DLL的方法,有3种:使用def文件/使用LoadLibrary和GetProcAddress方法/使用导出的lib配合头文件。
第一种太麻烦这里不介绍,只说明一下后两种的使用方法。
 1  #include  < iostream >
 2  #include  < windows.h >
 3 
 4  typedef  void  ( * SET)( int );
 5  typedef  int  ( * GET)( void );
 6  typedef  void  ( * SAYHELLO)( void );
 7 
 8  int  main( int  argc,  char   ** argv)
 9  {
10      SET pSet  =   0 ;
11      GET pGet  =   0 ;
12      SAYHELLO pSayHello  =   0 ;
13 
14      HINSTANCE hinst = ::LoadLibrary( " DLLImplement.dll " );
15       if  ( 0   ==  hinst)
16      {
17          std::cout << " load dll failed! " << std::endl;
18           return   - 1 ;
19      }
20 
21      pSet  =  (SET)GetProcAddress(hinst,  " Set " );
22      pGet  =  (GET)GetProcAddress(hinst,  " Get " );
23      pSayHello  =  (SAYHELLO)GetProcAddress(hinst,  " SayHello " );
24 
25       if  ( 0   ==  pSet  ||   0   ==  pGet  ||   0   ==  pSayHello)
26      {
27          std::cout << " get function failed! " << std::endl;
28           return   - 1 ;
29      }
30 
31       // ready to call the function
32      ( * pSet)( 10 );
33       int  i  =  ( * pGet)();
34      std::cout << " Get value from dll, value is  " << i << std::endl;
35      ( * pSayHello)();
36 
37       return   0 ;
38  }
这种调用方法属于显示调用,使用的时候需要知道DLL文件的路径,还有DLL里面的方法的名字,还是有点不太方便。更多的时候,都是使用最后一种隐式调用的方法,即配合头文件和导出的lib,需要在进行链接的时候加入DLLImplement.lib即可,方法如下:
 1  #include  < iostream >
 2  #include  " DLLHeader.h "
 3 
 4  using   namespace  std;
 5 
 6 
 7  int  main ( int  argc,  char   ** argv)
 8  {
 9      Set( 100 );
10      cout << " Set value in DLL " << endl;
11       int  i  =  Get();
12      cout << " Get value in DLL, value is  " << i << endl;
13 
14      SayHello();
15       return   0 ;
16  }
到这里对DLL有了一个大概的感性认识,具体的理论性的知识,等有机会慢慢再写出来。

抱怨一句,最近有点懒了,想要写的日志都没写。
找实习也麻烦,写代码肩膀脖子酸痛。
IT民工的命咋就这么苦哩。

你可能感兴趣的:(Windows动态链接库DLL[实践])