DLL函数指针调用小技巧
2008-08-26 10:29 ubunoon 阅读(2017) 评论(2) 编辑 收藏 举报
在C/C++编写的Dll调用中,有时候需要采用LoadLibrary来载入动态链接库,这个时候,我们需要调用的函数需要通过GetProcAddress来获取,很多时候,我们需要在载入之前,先定义函数的指针,然后再定义一个函数变量,然后将GetProcAddress获取的指针值强制转换为我们需要的指针。如下面代码所示:
但是如果采用下面的方式编写,则可以减少一定的代码输入,也不需要为每一个函数增加一个typedef类型,毕竟每一个函数都是唯一的,于是代码可以写成这样:
如果没有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 if( 0 == 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版本中将出现编译错误!
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 }
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将是全局变量,可以在任何地方使用。2
3 HANDLE hDll = LoadLibrary("your.dll");
4 if( NULL != hDll)
5 {
6 (FARPROC) lpAdd = GetProcAddress("add");
7
8 // other code
9 }
如果没有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 if( 0 == 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版本中将出现编译错误!
/*
*
* Copyright (c) 2011 Ubunoon.
* All rights reserved.
*
* email: netubu#gmail.com replace '#' to '@'
* http://www.cnblogs.com/ubunoon
* 欢迎来邮件定制各类验证码识别,条码识别,图像处理等软件
* 推荐不错的珍珠饰品,欢迎订购 * 宜臣珍珠(淡水好珍珠) */
*
* Copyright (c) 2011 Ubunoon.
* All rights reserved.
*
* email: netubu#gmail.com replace '#' to '@'
* http://www.cnblogs.com/ubunoon
* 欢迎来邮件定制各类验证码识别,条码识别,图像处理等软件
* 推荐不错的珍珠饰品,欢迎订购 * 宜臣珍珠(淡水好珍珠) */