Windows API GetProcAddress 及demo code

GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。

  函数原型:

  FARPROC GetProcAddress(

  HMODULE hModule, // DLL模块句柄

  LPCSTR lpProcName// 函数名

  );

 参数:

 hModule

  [in] 包含此函数的DLL模块的句柄。LoadLibrary、AfxLoadLibrary 或者GetModuleHandle函数可以返回此句柄。

  lpProcName

  [in] 包含函数名的以NULL结尾的字符串,或者指定函数的序数值。如果此参数是一个序数值,它必须在一个字的底字节,高字节必须为0。

  返回值:

  如果函数调用成功,返回值是DLL中的输出函数地址。

  如果函数调用失败,返回值是NULL。得到进一步的错误信息,调用函数GetLastError。

 

FARPROC 是一个4字节指针,指向一个函数的内存地址,例如
GetProcAddress 的返回类型就是一个FARPROC。
如果你要存放这个地址,可以声明以一个 FARPROC变量来存放。

 

GetProcAddress返回的是一个函数地址的指针。
声明:FARPROC WINAPI GetProcAddress(__in HMODULE hModule, __in LPCSTR LpProcName);
你应该知道你要的函数的类型是什么,可以用typedef的方法定义函数类型,然后定义一个这种类型的变量,你得到地址后,将地址的类型转换并存到那个变量中就行了。例如:

 这是RunHook定义:
BOOL _stdcall RunHook(HMODULE hModule,DWORD dwThreadId)
{
HWndHook=::SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HOOKProc,hMod,dwThreadId);
return TRUE;
}

这是全局声明:
typedef BOOL (_stdcall *funRunHook)(HMODULE hModule,DWORD dwThreadID);

这两种调用都不行:
funRunHook RunHook;
RunHook=(funRunHook)GetProcAddress(hMod,"RunHook");


LoadLibrary
Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long

说明

载入指定的动态链接库,并将它映射到 当前进程使用的地址空间。一旦载入,即可访问库内保存的资源

返回值

Long,成功则返回库模块的句柄,零表示失败。会设置GetLastError
参数 类型及说明
lpLibFileName String,指定要载入的动态链接库的名称。采用与CreateProcess函数的lpCommandLine参数指定的同样的搜索顺序
注解
一旦不需要,用FreeLibrary函数释放DLL

**********************************************************************************************************************************************************

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


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

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

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. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值