本文共 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()#endifDll的导出函数
// 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!