使用 GetProcAddress Function 时,有以下几点需要特别留意

1. 第二个参数类型是 LPCSTR,不是 

2.  __declspec(dllexport),按 C 名称修饰(extern "C" 导出的函数名,对于 __stdcall  __fastcall 调用约定是相同的;对 __cdecl 是不同的(导出的函数名没有前面的下划线)

3. 即使返回值不是 NULL,也有可能发生错误。当 .def 模块不是连续地从 1 开始编号 ordinal 值,那么,如果用一个无函数对应的 ordinal 值调用 GetProcAddress,就会发生错误,返回一个无效的非 NULL 地址; 

4. 最好用函数名,而不是 ordinal 值调用 GetProcAddress,以避免不同版本 Dll 中某些函数不存在的情况

注:确认 Dll 的导出函数名,可以用 DUMPBIN /EXPORTS dll_file_name.dll 命令,然后查看 name 

[cpp] view plain copy

 print?

  1. // The myPuts function writes a null-terminated string to  
  2. // the standard output device.  
  3.      
  4. // The export mechanism used here is the __declspec(export)  
  5. // method supported by Microsoft Visual Studio, but any  
  6. // other export method supported by your development  
  7. // environment may be substituted.  
  8.      
  9.      
  10. #include <windows.h>  
  11.      
  12. #define EOF (-1)  
  13.      
  14. #ifdef __cplusplus    // If used by C++ code,   
  15. extern "C" {          // we need to export the C interface  
  16. #endif  
  17.      
  18. __declspec(dllexportint __cdecl myPuts(LPTSTR lpszMsg) // __cdecl | __stdcall | __fastcall  
  19. {  
  20.     DWORD cchWritten;  
  21.     HANDLE hStdout;  
  22.     BOOL fRet;  
  23.      
  24.     // Get a handle to the standard output device.  
  25.      
  26.     hStdout = GetStdHandle(STD_OUTPUT_HANDLE);  
  27.     if (INVALID_HANDLE_VALUE == hStdout)  
  28.         return EOF;  
  29.      
  30.     // Write a null-terminated string to the standard output device.  
  31.      
  32.     while (*lpszMsg != '\0')  
  33.     {  
  34.         fRet = WriteFile(hStdout, lpszMsg, 1, &cchWritten, NULL);  
  35.         if( (FALSE == fRet) || (1 != cchWritten) )  
  36.             return EOF;  
  37.         lpszMsg++;  
  38.     }  
  39.      
  40.     return 1;  
  41. }  
  42.      
  43. #ifdef __cplusplus  
  44. }  
  45. #endif  

[cpp] view plain copy

 print?

  1. // A simple program that uses LoadLibrary and   
  2. // GetProcAddress to access myPuts from Myputs.dll.   
  3.      
  4. #include <stdio.h>   
  5. #include <windows.h>   
  6.      
  7. typedef int (__cdecl *MYPROC)(LPTSTR); // __cdecl | __stdcall | __fastcall  
  8.      
  9. VOID main(VOID)   
  10. {   
  11.     HINSTANCE hinstLib;   
  12.     MYPROC ProcAdd;   
  13.     BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;   
  14.      
  15.     // Get a handle to the DLL module.  
  16.      
  17.     hinstLib = LoadLibrary(TEXT("bin\\Myputs")); // 虽然 MSDN Library 说这里如果  
  18.                                                  // 指定了路径,要用 backslashes (\)  
  19.                                                  // 不要用 forward slashes (/),但  
  20.                                                  // 其实用二者都可以。  
  21.                                                  // 注:如果用 \,要用 \\  
  22.      
  23.     // If the handle is valid, try to get the function address.  
  24.      
  25.     if (hinstLib != NULL)   
  26.     {   
  27.         ProcAdd = (MYPROC)GetProcAddress(hinstLib, "myPuts"); // __cdecl   : myPuts  
  28.                                                               // __stdcall : _myPuts@4  
  29.                                                               // __fastcall: @myPuts@4  
  30.      
  31.         // If the function address is valid, call the function.  
  32.      
  33.         if (NULL != ProcAdd)   
  34.         {  
  35.             fRunTimeLinkSuccess = TRUE;  
  36.             (ProcAdd) (TEXT("Message via DLL function\n"));   
  37.         }  
  38.      
  39.         // Free the DLL module.  
  40.      
  41.         fFreeResult = FreeLibrary(hinstLib);   
  42.     }   
  43.      
  44.     // If unable to call the DLL function, use an alternative.  
  45.      
  46.     if (! fRunTimeLinkSuccess)   
  47.         printf("Message via alternative method\n");   
  48. }  

原文:http://blog.csdn.net/g5dsk/article/details/6680698

posted on 2016-07-05 11:29  今夜太冷  阅读(14014)  评论(0编辑  收藏  举报