实验: 显式装入DLL时, DLL接口操作封装类
发布日期:2021-06-30 22:14:46 浏览次数:3 分类:技术文章

本文共 13763 字,大约阅读时间需要 45 分钟。

/**

* @brief 动态装载, 使用Dll的简单方法

* @note LostSpeed modify LateLoad.h at 2011_1127_0327

* update to fit unicode

* fix error on LATELOAD_FUNC_9_VOID

* add LATELOAD_FUNC_10, LATELOAD_FUNC_11, LATELOAD_FUNC_12

* add LATELOAD_FUNC_11_VOID, LATELOAD_FUNC_11_VOID, LATELOAD_FUNC_12_VOID

*

* 开发环境: winxpSp3 + vs2005 sp1 + unicode

*/

隐式装入DLL时, 需要包含dll.h, dll.lib, 有时会引起编译问题.

如果是第三方的DLL, 有时也得不到dll.h, dll.lib.

 

显式操作DLL时, 如果直接使用 LoadLibrary, GetProcAddress, 特别是DLL函数接口较多时, 代码繁琐,不整洁.

 

找到资料, 用来解决这一问题. 他的方法是使用基类 + 宏, 使函数接口操作, 书写简单化.

/**

* @file LateLoad.h
* @note from http://www.codeproject.com/KB/DLL/LateLoad.aspx
*    LateLoad DLL Wrapper
*    By Jason De Arte | 1 Mar 2004

*/

/*** @file CallDllDynamic.cpp* @brief 动态调用DLL* @note/n*	对于标准DLL, 不导出类, 只导出C类型接口函数的情况/n*	这种DLL接口操作封装很管用, 代码整洁, 操作简单/n**	当DLL不存在时, Loadlibrary时失败, 不做额外的判断/n**	当DLL不存在时, 当用到DLL函数指针时, 是无效的函数指针/n*	先调用classX.Is_XX(), 确定DLL函数指针是否有效*	再调用接口classX.fnXX, 来执行DLL提供的功能**	当DLL存在, DLL接口名称正确, 接口参数列表错误时, 直接报错*	这是正常的情况, 用错了参数自然会错.*	在调用方加入try, catch没用. 要加入到LATELOAD_FUNC_x中**	fix: LATELOAD_FUNC_1宏中加入了try, catch来控制这种上述报错情况的发生*	@warning: 用try, catch捕获不到这种错误, 暂时解决不了!*	参数用错这种情况,在实际应用中很少见. 除非是针对第三方DLL的实验~*	TODO: 其他的LATELOAD_FUNC_x 和 LATELOAD_FUNC_x_VOID 需要照此办理**	实验环境: winxpSp3 + vs2008 + UNICODE*	按照原始资料的说明: http://www.codeproject.com/KB/DLL/LateLoad.aspx*	fix: UNICODE环境下, dll_LoadLibrary(_T(#ModuleName),bLoadDllNow);** @date 2011-05-15* @version 1.0.0.1*/#include "stdafx.h"#include 
#include
#include
#include
#include
//for W2A#include
#include "LateLoad.h"/*** 常量定义*/#define G_OBJDLL_NAME _T("RealDll.dll") /**< 目标DLL名称 */#define G_OBJDLL_METHOD_NAME1 _T("fnRealDll") /**< 目标DLL方法名称 */#define G_OBJDLL_METHOD_POINTER1 fnRealDll /**< 目标DLL方法指针 */LATELOAD_BEGIN_CLASS(CRealDllHelper,RealDll,FALSE,FALSE)/*** DLL存在, 正确的导出函数定义* 经过测试, DLL导出函数工作正确*///LATELOAD_FUNC_0(-1,INT,__stdcall,fnRealDll)/*** 增加一个不存在或错误的DLL导出函数名 * 用来测试DLL存在, 但是导出函数不存在或手误的情况*/LATELOAD_FUNC_0(-1,INT,__stdcall,fnNotExsit)/*** 增加一个正确的DLL导出函数名, 但是参数不正确* 用来测试DLL存在, 但是参数不正确的情况* * @warning 这种情况直接报错!*/LATELOAD_FUNC_1(-1,INT,__stdcall,fnRealDll, INT)LATELOAD_END_CLASS()/*** @fn INT CheckDll()* @brief 检查DLL是否正确, 标准的显式使用DLL的方法* @note 动态调用DLL, 用GetProcessAddr的方法取得DLL函数* @return INT* @retval S_OK, success* @retval 非S_OK, failed*/INT CheckDll();/*** @fn INT CheckDllLateLoad()* @brief 用LATELOAD封装来操作DLL* @return INT* @retval S_OK, success* @retval 非S_OK, failed*/INT CheckDllLateLoad();int _tmain(int argc, _TCHAR* argv[]){// if(S_OK != CheckDll())// {// _tprintf(_T("[S_FALSE]CheckDll/n"));// return -1;// }// else// _tprintf(_T("[S_OK]CheckDll/n")); if(!CheckDllLateLoad()) { _tprintf(_T("[S_FALSE]CheckDllLateLoad/n")); return -1; } else _tprintf(_T("[S_OK]CheckDllLateLoad/n")); _tprintf(_T("END/n")); return 0;}INT CheckDllLateLoad(){ INT nRc = 0; CRealDllHelper RealDllHelper; /** * 正确的情况 */// if(!RealDllHelper.Is_fnRealDll())// return S_FALSE;// nRc = RealDllHelper.fnRealDll(); /** * 函数名不存在时, 返回-1 */// if(!RealDllHelper.Is_fnNotExsit())// return S_FALSE;// nRc = RealDllHelper.fnNotExsit(); /** * 测试DLL存在, DLL函数名正确, 参数不正确的情况 * 直接报错! */ try { if(!RealDllHelper.Is_fnRealDll()) return S_FALSE; nRc = RealDllHelper.fnRealDll(123); } catch (...) { _tprintf(_T("参数列表可能不对/n")); return S_FALSE; } return S_OK;}INT CheckDll(){ USES_CONVERSION; //for W2A HMODULE hDll = ::LoadLibrary(G_OBJDLL_NAME); if(!hDll) return S_FALSE; FARPROC G_OBJDLL_METHOD_POINTER1; G_OBJDLL_METHOD_POINTER1 = ::GetProcAddress(hDll, W2A(G_OBJDLL_METHOD_NAME1)); if(!G_OBJDLL_METHOD_POINTER1) return S_FALSE; INT nRc = G_OBJDLL_METHOD_POINTER1(); ::FreeLibrary(hDll); return S_OK;}

 

延迟装入DLL的资料:

http://www.codeproject.com/KB/DLL/delayloaddll.aspx

 

延迟装入DLL也解决不了, DLL接口函数参数列表用错的情况~

 

<2011_1127>

修改了LateLoad.h, 重新验证一个完整的DllHelper.

// srcDynamicCallDll.cpp : Defines the entry point for the console application.///*** @note LostSpeed modify LateLoad.h at 2011_1127_0327* update to fit unicode* fix error on LATELOAD_FUNC_9_VOID* add LATELOAD_FUNC_10, LATELOAD_FUNC_11, LATELOAD_FUNC_12* add LATELOAD_FUNC_11_VOID, LATELOAD_FUNC_11_VOID, LATELOAD_FUNC_12_VOID*/#include "stdafx.h"#include "DllForTestHelper.h"CsrcDllForTestHelper DllTestHelper;int _tmain(int argc, _TCHAR* argv[]){	INT iRc = S_FALSE;	iRc = DllTestHelper.fnsrcDllForTest_param0();	iRc = DllTestHelper.fnsrcDllForTest_param1(1);	iRc = DllTestHelper.fnsrcDllForTest_param2(1,2);	iRc = DllTestHelper.fnsrcDllForTest_param3(1,2,3);	iRc = DllTestHelper.fnsrcDllForTest_param4(1,2,3,4);	iRc = DllTestHelper.fnsrcDllForTest_param5(1,2,3,4,5);	iRc = DllTestHelper.fnsrcDllForTest_param6(1,2,3,4,5,6);	iRc = DllTestHelper.fnsrcDllForTest_param7(1,2,3,4,5,6,7);	iRc = DllTestHelper.fnsrcDllForTest_param8(1,2,3,4,5,6,7,8);	iRc = DllTestHelper.fnsrcDllForTest_param9(1,2,3,4,5,6,7,8,9);	iRc = DllTestHelper.fnsrcDllForTest_param10(1,2,3,4,5,6,7,8,9,10);	iRc = DllTestHelper.fnsrcDllForTest_param11(1,2,3,4,5,6,7,8,9,10,11);	iRc = DllTestHelper.fnsrcDllForTest_param12(1,2,3,4,5,6,7,8,9,10,11,12);	DllTestHelper.fnsrcDllForTest_noRc_param0();	DllTestHelper.fnsrcDllForTest_noRc_param1(1);	DllTestHelper.fnsrcDllForTest_noRc_param2(1,2);	DllTestHelper.fnsrcDllForTest_noRc_param3(1,2,3);	DllTestHelper.fnsrcDllForTest_noRc_param4(1,2,3,4);	DllTestHelper.fnsrcDllForTest_noRc_param5(1,2,3,4,5);	DllTestHelper.fnsrcDllForTest_noRc_param6(1,2,3,4,5,6);	DllTestHelper.fnsrcDllForTest_noRc_param7(1,2,3,4,5,6,7);	DllTestHelper.fnsrcDllForTest_noRc_param8(1,2,3,4,5,6,7,8);	DllTestHelper.fnsrcDllForTest_noRc_param9(1,2,3,4,5,6,7,8,9);	DllTestHelper.fnsrcDllForTest_noRc_param10(1,2,3,4,5,6,7,8,9,10);	DllTestHelper.fnsrcDllForTest_noRc_param11(1,2,3,4,5,6,7,8,9,10,11);	DllTestHelper.fnsrcDllForTest_noRc_param12(1,2,3,4,5,6,7,8,9,10,11,12);	_tprintf(_T("END, press any key to quit\n"));	/** run results	>> fnsrcDllForTest_param0	<< fnsrcDllForTest_param0	>> fnsrcDllForTest_param1	<< fnsrcDllForTest_param1	>> fnsrcDllForTest_param2	<< fnsrcDllForTest_param2	>> fnsrcDllForTest_param3	<< fnsrcDllForTest_param3	>> fnsrcDllForTest_param4	<< fnsrcDllForTest_param4	>> fnsrcDllForTest_param5	<< fnsrcDllForTest_param5	>> fnsrcDllForTest_param6	<< fnsrcDllForTest_param6	>> fnsrcDllForTest_param7	<< fnsrcDllForTest_param7	>> fnsrcDllForTest_param8	<< fnsrcDllForTest_param8	>> fnsrcDllForTest_param9	<< fnsrcDllForTest_param9	>> fnsrcDllForTest_param10	<< fnsrcDllForTest_param10	>> fnsrcDllForTest_param11	<< fnsrcDllForTest_param11	>> fnsrcDllForTest_param12	<< fnsrcDllForTest_param12	>> fnsrcDllForTest_noRc_param0	<< fnsrcDllForTest_noRc_param0	>> fnsrcDllForTest_noRc_param1	<< fnsrcDllForTest_noRc_param1	>> fnsrcDllForTest_noRc_param2	<< fnsrcDllForTest_noRc_param2	>> fnsrcDllForTest_noRc_param3	<< fnsrcDllForTest_noRc_param3	>> fnsrcDllForTest_noRc_param4	<< fnsrcDllForTest_noRc_param4	>> fnsrcDllForTest_noRc_param5	<< fnsrcDllForTest_noRc_param5	>> fnsrcDllForTest_noRc_param6	<< fnsrcDllForTest_noRc_param6	>> fnsrcDllForTest_noRc_param7	<< fnsrcDllForTest_noRc_param7	>> fnsrcDllForTest_noRc_param8	<< fnsrcDllForTest_noRc_param8	>> fnsrcDllForTest_noRc_param9	<< fnsrcDllForTest_noRc_param9	>> fnsrcDllForTest_noRc_param10	<< fnsrcDllForTest_noRc_param10	>> fnsrcDllForTest_noRc_param11	<< fnsrcDllForTest_noRc_param11	>> fnsrcDllForTest_noRc_param12	<< fnsrcDllForTest_noRc_param12	END, press any key to quit	*/	getchar();	return 0;}
/*** @file DllForTestHelper.h*/#ifndef _DLL_FOR_TEST_HELPER_H_#define _DLL_FOR_TEST_HELPER_H_#include "LateLoad.h"#define ERROR_BASE 100#define E_FALSE ERROR_BASE + 1LATELOAD_BEGIN_CLASS(CsrcDllForTestHelper,srcDllForTest,FALSE,TRUE)LATELOAD_FUNC_0(E_FALSE,INT,WINAPI,fnsrcDllForTest_param0)LATELOAD_FUNC_1(E_FALSE,INT,WINAPI,fnsrcDllForTest_param1,INT)LATELOAD_FUNC_2(E_FALSE,INT,WINAPI,fnsrcDllForTest_param2,INT,INT)LATELOAD_FUNC_3(E_FALSE,INT,WINAPI,fnsrcDllForTest_param3,INT,INT,INT)LATELOAD_FUNC_4(E_FALSE,INT,WINAPI,fnsrcDllForTest_param4,INT,INT,INT,INT)LATELOAD_FUNC_5(E_FALSE,INT,WINAPI,fnsrcDllForTest_param5,INT,INT,INT,INT,INT)LATELOAD_FUNC_6(E_FALSE,INT,WINAPI,fnsrcDllForTest_param6,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_7(E_FALSE,INT,WINAPI,fnsrcDllForTest_param7,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_8(E_FALSE,INT,WINAPI,fnsrcDllForTest_param8,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_9(E_FALSE,INT,WINAPI,fnsrcDllForTest_param9,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_10(E_FALSE,INT,WINAPI,fnsrcDllForTest_param10,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_11(E_FALSE,INT,WINAPI,fnsrcDllForTest_param11,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_12(E_FALSE,INT,WINAPI,fnsrcDllForTest_param12,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_0_VOID(WINAPI,fnsrcDllForTest_noRc_param0)LATELOAD_FUNC_1_VOID(WINAPI,fnsrcDllForTest_noRc_param1,INT)LATELOAD_FUNC_2_VOID(WINAPI,fnsrcDllForTest_noRc_param2,INT,INT)LATELOAD_FUNC_3_VOID(WINAPI,fnsrcDllForTest_noRc_param3,INT,INT,INT)LATELOAD_FUNC_4_VOID(WINAPI,fnsrcDllForTest_noRc_param4,INT,INT,INT,INT)LATELOAD_FUNC_5_VOID(WINAPI,fnsrcDllForTest_noRc_param5,INT,INT,INT,INT,INT)LATELOAD_FUNC_6_VOID(WINAPI,fnsrcDllForTest_noRc_param6,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_7_VOID(WINAPI,fnsrcDllForTest_noRc_param7,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_8_VOID(WINAPI,fnsrcDllForTest_noRc_param8,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_9_VOID(WINAPI,fnsrcDllForTest_noRc_param9,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_10_VOID(WINAPI,fnsrcDllForTest_noRc_param10,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_11_VOID(WINAPI,fnsrcDllForTest_noRc_param11,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_FUNC_12_VOID(WINAPI,fnsrcDllForTest_noRc_param12,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT)LATELOAD_END_CLASS()#endif
Dll的导出函数

// The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the SRCDLLFORTEST_EXPORTS// symbol defined on the command line. this symbol should not be defined on any project// that uses this DLL. This way any other project whose source files include this file see // SRCDLLFORTEST_API functions as being imported from a DLL, whereas this DLL sees symbols// defined with this macro as being exported.#ifdef SRCDLLFORTEST_EXPORTS#define SRCDLLFORTEST_API __declspec(dllexport)#else#define SRCDLLFORTEST_API __declspec(dllimport)#endif/** 有返回值函数 */SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param0(void);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param1(INT param1);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param2(INT param1, INT param2);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param3(	INT param1, INT param2, INT param3);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param4(	INT param1, INT param2, INT param3, INT param4);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param5(	INT param1, INT param2, INT param3, INT param4, INT param5);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param6(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param7(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param8(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param9(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param10(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9, INT param10);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param11(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9, INT param10, INT param11);SRCDLLFORTEST_API int WINAPI fnsrcDllForTest_param12(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9, INT param10, INT param11, INT param12);/** 无返回值函数 */SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param0(void);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param1(INT param1);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param2(INT param1, INT param2);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param3(	INT param1, INT param2, INT param3);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param4(	INT param1, INT param2, INT param3, INT param4);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param5(	INT param1, INT param2, INT param3, INT param4, INT param5);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param6(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param7(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param8(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param9(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param10(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9, INT param10);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param11(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9, INT param10, INT param11);SRCDLLFORTEST_API void WINAPI fnsrcDllForTest_noRc_param12(	INT param1, INT param2, INT param3, INT param4, INT param5, INT param6, 	INT param7, INT param8, INT param9, INT param10, INT param11, INT param12);

转载地址:https://lostspeed.blog.csdn.net/article/details/6423137 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:资源: 辅助工具
下一篇:查找纯win32c++程序的内存泄漏

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月21日 04时19分20秒