代码改变世界

DLL函数指针调用小技巧

2008-08-26 10:29  ubunoon  阅读(2017)  评论(2编辑  收藏  举报
在C/C++编写的Dll调用中,有时候需要采用LoadLibrary来载入动态链接库,这个时候,我们需要调用的函数需要通过GetProcAddress来获取,很多时候,我们需要在载入之前,先定义函数的指针,然后再定义一个函数变量,然后将GetProcAddress获取的指针值强制转换为我们需要的指针。如下面代码所示:
 1 typedef int (*ADD)(int m, int n);
 2 
 3 HANDLE hDll = LoadLibrary("your.dll");
 4 ADD add;
 5 if( NULL != hDll )
 6 {
 7     add = (ADD) GetProcAddress("add");
 8 
 9     // other code
10 }

但是如果采用下面的方式编写,则可以减少一定的代码输入,也不需要为每一个函数增加一个typedef类型,毕竟每一个函数都是唯一的,于是代码可以写成这样:
1 int (WINAPI* lpAdd) (int m, int n);
2 
3 HANDLE hDll = LoadLibrary("your.dll");
4 if( NULL != hDll)
5 {
6     (FARPROC) lpAdd = GetProcAddress("add");
7      
8      //  other code 
9 }
对每一个需要用GetProcAddress复制的变量,均用(FARPROC)强制定义,并且lpAdd将是全局变量,可以在任何地方使用。

如果没有lib文件提供,可以通过下面的方式,来显示提供lib的功能,并且这种方式又可以是动态的方式加载,因此比lib更具有灵活性:
 1 int (WINAPI* lpAdd) (int m, int n);
 2 
 3 static int iLoadNum = 0;          // static不会扩散到其他文件中
 4 static HANDLE hDll = NULL;
 5 
 6 BOOL LoadYourDLL()
 7 {
 8     if ( NULL == hDll )
 9     {
10         hDll = LoadLibrary("your.dll");
11     }
12     
13     if(  NULL == hDll )
14     {
15         return FALSE;
16     }
17     
18     if0 == iLoadNum )
19     {
20         (FARPROC )lpAdd = GetProcAddress(hDll, "add");
21     }
22     
23     iLoadNum ++;
24     return TRUE;
25 }
26 
27 INT FreeYourDLL()
28 {
29     iLoadNum--;
30 
31     if( iLoadNum == 0)
32     {
33         FreeLibrary( hDll );
34         hDll = NULL;
35     }
36     return iLoadNum;
37 }
38 
39 int add( int m, int n)
40 {
41 //     LoadYourDLL();
42      int ret = lpAdd(m,n);
43 //     FreeYourDLL();
44      return ret;
45 }
46 
如果采用这种方式编写dll的调用文件,那么在需要载入dll的地方调用LoadYourDLL()函数,然后就可以与使用lib文件一样的方式直接使用add函数来应用dll中的函数,而且名称没有改变,这样,更加方便移植,如果将LoadYourDLL与FreeYourDLL封装为C++的某个类,那么执行dll中的函数将与普通的调用调用函数一致。

这个方法在BCB中可以应用,在vs2005版本中将出现编译错误!