同学们动态加载dll的时候是不是感觉挺麻烦的,每次都::LoadLibrary,::GetProcAddress,还要typedef一堆函数。最近闲来无聊,用宏封装了一下,可以少写不少代码,用来也挺方便的。
不过最多支持5个参数,同学们可以自己加。等着下次用flexbison写一个生成工具,我感觉还是不错的。
1 #pragma once 2 /*! \brief 动态加载dll,并调用导出函数 3 author:[email protected] 4 */ 5 #define DLLLOADER_BEGIN( NAME)\ 6 class DLLLOADER_##NAME\ 7 {\ 8 public:\ 9 static BOOL Init( LPCWSTR sDllPath){\ 10 if ( RefHModule())\ 11 {\ 12 return TRUE;\ 13 }\ 14 RefHModule() = ::LoadLibrary( sDllPath);\ 15 if ( !RefHModule())\ 16 {\ 17 return FALSE;\ 18 }\ 19 return TRUE;\ 20 }\ 21 static void UnInit(){\ 22 if ( RefHModule())\ 23 {\ 24 FreeLibrary( RefHModule());\ 25 RefHModule() = NULL;\ 26 }\ 27 }\ 28 static HMODULE& RefHModule(){\ 29 static HMODULE M = NULL;\ 30 return M;\ 31 } 32 #define DLLLOADER_ENTRY_0( FUNNAME, FUNDESC, FUNRET, FUNRETDEF)\ 33 typedef FUNRET (FUNDESC *_##FUNNAME)();\ 34 static _##FUNNAME Ref##FUNNAME(){\ 35 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 36 return F;\ 37 }\ 38 static FUNRET FUNNAME(){\ 39 if ( Ref##FUNNAME())\ 40 {\ 41 return Ref##FUNNAME()();\ 42 }\ 43 return FUNRETDEF;\ 44 } 45 #define DLLLOADER_ENTRY_VOID0( FUNNAME, FUNDESC)\ 46 typedef void (FUNDESC *_##FUNNAME)();\ 47 static _##FUNNAME Ref##FUNNAME(){\ 48 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 49 return F;\ 50 }\ 51 static void FUNNAME(){\ 52 if ( Ref##FUNNAME())\ 53 {\ 54 Ref##FUNNAME()();\ 55 }\ 56 } 57 #define DLLLOADER_ENTRY_1( FUNNAME, FUNDESC, FUNRET, FUNRETDEF, PARAMTYPE1)\ 58 typedef FUNRET (FUNDESC *_##FUNNAME)(PARAMTYPE1);\ 59 static _##FUNNAME Ref##FUNNAME(){\ 60 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 61 return F;\ 62 }\ 63 static FUNRET FUNNAME( PARAMTYPE1 PARAM1){\ 64 if ( Ref##FUNNAME())\ 65 {\ 66 return Ref##FUNNAME()( PARAM1);\ 67 }\ 68 return FUNRETDEF;\ 69 } 70 #define DLLLOADER_ENTRY_VOID1( FUNNAME, FUNDESC, PARAMTYPE1)\ 71 typedef void (FUNDESC *_##FUNNAME)(PARAMTYPE1);\ 72 static _##FUNNAME Ref##FUNNAME(){\ 73 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 74 return F;\ 75 }\ 76 static void FUNNAME( PARAMTYPE1 PARAM1){\ 77 if ( Ref##FUNNAME())\ 78 {\ 79 Ref##FUNNAME()( PARAM1);\ 80 }\ 81 } 82 #define DLLLOADER_ENTRY_2( FUNNAME, FUNDESC, FUNRET, FUNRETDEF, PARAMTYPE1, PARAMTYPE2)\ 83 typedef FUNRET (FUNDESC *_##FUNNAME)(PARAMTYPE1, PARAMTYPE2);\ 84 static _##FUNNAME Ref##FUNNAME(){\ 85 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 86 return F;\ 87 }\ 88 static FUNRET FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2){\ 89 if ( Ref##FUNNAME())\ 90 {\ 91 return Ref##FUNNAME()( PARAM1, PARAM2);\ 92 }\ 93 return FUNRETDEF;\ 94 } 95 #define DLLLOADER_ENTRY_VOID2( FUNNAME, FUNDESC, PARAMTYPE1, PARAMTYPE2)\ 96 typedef void (FUNDESC *_##FUNNAME)(PARAMTYPE1, PARAMTYPE2);\ 97 static _##FUNNAME Ref##FUNNAME(){\ 98 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 99 return F;\ 100 }\ 101 static void FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2){\ 102 if ( Ref##FUNNAME())\ 103 {\ 104 Ref##FUNNAME()( PARAM1, PARAM2);\ 105 }\ 106 } 107 #define DLLLOADER_ENTRY_3( FUNNAME, FUNDESC, FUNRET, FUNRETDEF, PARAMTYPE1, PARAMTYPE2, PARAMTYPE3)\ 108 typedef FUNRET (FUNDESC *_##FUNNAME)(PARAMTYPE1, PARAMTYPE2, PARAMTYPE3);\ 109 static _##FUNNAME Ref##FUNNAME(){\ 110 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 111 return F;\ 112 }\ 113 static FUNRET FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2, PARAMTYPE3 PARAM3){\ 114 if ( Ref##FUNNAME())\ 115 {\ 116 return Ref##FUNNAME()( PARAM1, PARAM2, PARAM3);\ 117 }\ 118 return FUNRETDEF;\ 119 } 120 #define DLLLOADER_ENTRY_VOID3( FUNNAME, FUNDESC, PARAMTYPE1, PARAMTYPE2, PARAMTYPE3)\ 121 typedef void (FUNDESC *_##FUNNAME)(PARAMTYPE1, PARAMTYPE2, PARAMTYPE3);\ 122 static _##FUNNAME Ref##FUNNAME(){\ 123 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 124 return F;\ 125 }\ 126 static void FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2, PARAMTYPE3 PARAM3){\ 127 if ( Ref##FUNNAME())\ 128 {\ 129 Ref##FUNNAME()( PARAM1, PARAM2, PARAM3);\ 130 }\ 131 } 132 #define DLLLOADER_ENTRY_4( FUNNAME, FUNDESC, FUNRET, FUNRETDEF, PARAMTYPE1,\ 133 PARAMTYPE2, PARAMTYPE3, PARAMTYPE4)\ 134 typedef FUNRET (FUNDESC *_##FUNNAME)(PARAMTYPE1, PARAMTYPE2, PARAMTYPE3, PARAMTYPE4);\ 135 static _##FUNNAME Ref##FUNNAME(){\ 136 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 137 return F;\ 138 }\ 139 static FUNRET FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2, PARAMTYPE3 PARAM3, PARAMTYPE4 PARAM4){\ 140 if ( Ref##FUNNAME())\ 141 {\ 142 return Ref##FUNNAME()( PARAM1, PARAM2, PARAM3, PARAM4);\ 143 }\ 144 return FUNRETDEF;\ 145 } 146 #define DLLLOADER_ENTRY_VOID4( FUNNAME, FUNDESC, PARAMTYPE1,\ 147 PARAMTYPE2, PARAMTYPE3, PARAMTYPE4)\ 148 typedef void (FUNDESC *_##FUNNAME)(PARAMTYPE1, PARAMTYPE2, PARAMTYPE3, PARAMTYPE4);\ 149 static _##FUNNAME Ref##FUNNAME(){\ 150 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 151 return F;\ 152 }\ 153 static void FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2, PARAMTYPE3 PARAM3, PARAMTYPE4 PARAM4){\ 154 if ( Ref##FUNNAME())\ 155 {\ 156 Ref##FUNNAME()( PARAM1, PARAM2, PARAM3, PARAM4);\ 157 }\ 158 } 159 #define DLLLOADER_ENTRY_5( FUNNAME, FUNDESC, FUNRET, FUNRETDEF, PARAMTYPE1,\ 160 PARAMTYPE2, PARAMTYPE3, PARAMTYPE4, PARAMTYPE5)\ 161 typedef FUNRET (FUNDESC *_##FUNNAME)(PARAMTYPE1, \ 162 PARAMTYPE2, PARAMTYPE3, PARAMTYPE4, PARAMTYPE5);\ 163 static _##FUNNAME Ref##FUNNAME(){\ 164 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 165 return F;\ 166 }\ 167 static FUNRET FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2, \ 168 PARAMTYPE3 PARAM3, PARAMTYPE4 PARAM4, PARAMTYPE5 PARAM5){\ 169 if ( Ref##FUNNAME())\ 170 {\ 171 return Ref##FUNNAME()( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5);\ 172 }\ 173 return FUNRETDEF;\ 174 } 175 #define DLLLOADER_ENTRY_VOID5( FUNNAME, FUNDESC, PARAMTYPE1,\ 176 PARAMTYPE2, PARAMTYPE3, PARAMTYPE4, PARAMTYPE5)\ 177 typedef void (FUNDESC *_##FUNNAME)(PARAMTYPE1, \ 178 PARAMTYPE2, PARAMTYPE3, PARAMTYPE4, PARAMTYPE5);\ 179 static _##FUNNAME Ref##FUNNAME(){\ 180 _##FUNNAME F = (_##FUNNAME)::GetProcAddress( RefHModule(), #FUNNAME);\ 181 return F;\ 182 }\ 183 static void FUNNAME( PARAMTYPE1 PARAM1, PARAMTYPE2 PARAM2, \ 184 PARAMTYPE3 PARAM3, PARAMTYPE4 PARAM4, PARAMTYPE5 PARAM5){\ 185 if ( Ref##FUNNAME())\ 186 {\ 187 Ref##FUNNAME()( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5);\ 188 }\ 189 } 190 #define DLLLOADER_END()\ 191 }; 192 193 /* 194 例子: 195 DLLLOADER_BEGIN( SAMPLE) 196 DLLLOADER_ENTRY_0( Function1, BOOL, FALSE, ) 197 DLLLOADER_ENTRY_VOID0( Function2, ) 198 DLLLOADER_ENTRY_1( Function3, BOOL, FALSE, , LPCWSTR) 199 DLLLOADER_END() 200 201 DLLLOADER_BEGIN(KERNEL32) 202 DLLLOADER_ENTRY_1( LoadLibraryW, WINAPI, HMODULE, 0, LPCWSTR) 203 DLLLOADER_ENTRY_3( GetModuleFileNameW, WINAPI, DWORD, 0, HMODULE, LPWSTR, DWORD) 204 DLLLOADER_END() 205 206 int _tmain(int argc, _TCHAR* argv[]) 207 { 208 DLLLOADER_SAMPLE::Init( L"C:\\Users\\sosopop\\Documents\\Visual Studio 2005\\Projects\\testHandle\\debug\\testLoadDll.dll"); 209 DLLLOADER_SAMPLE::Function1(); 210 DLLLOADER_SAMPLE::Function2(); 211 DLLLOADER_SAMPLE::Function3(L"Function3 Hello"); 212 DLLLOADER_SAMPLE::Function4(L"Function4", L"Hello"); 213 DLLLOADER_SAMPLE::UnInit(); 214 215 DLLLOADER_KERNEL32::Init( L"c:\\windows\\system32\\kernel32.dll"); 216 HMODULE h =DLLLOADER_KERNEL32::LoadLibraryW( L"user32.dll"); 217 WCHAR sFileName[MAX_PATH]={0}; 218 DWORD nSize = DLLLOADER_KERNEL32::GetModuleFileNameW( NULL, sFileName, _countof(sFileName)); 219 220 return 0; 221 } 222 */