Windows程序中加載並使用動態連接庫

1 GetProcAddress()

1.1函數原型

GetProcAddress函數檢索指定的動態連接庫(DLL)中的輸出庫函數地址。 less

函數原型:
FARPROC GetProcAddress(
HMODULE hModule, // DLL模塊句柄
LPCSTR lpProcName // 函數名
);
hModule
[in] 包含此函數的DLL模塊的句柄。LoadLibrary、 AfxLoadLibrary  或者GetModuleHandle函數能夠返回此句柄。
lpProcName
[in] 包含函數名的以NULL結尾的字符串,或者指定函數的序數值。若是此參數是一個序數值,它必須在一個字的底字節,高字節必須爲0。
返回值:
若是 函數調用成功,返回值是DLL中的輸出函數地址。
若是 函數調用失敗,返回值是NULL。獲得進一步的 錯誤信息,調用函數GetLastError。

1.2 註釋

GetProcAddress函數被用來檢索在DLL中的輸出函數地址。
lpProcName 指針指向的函數名,拼寫和大小寫必須和DLL 源代碼中的 模塊定義文件(.DEF)中輸出段(EXPORTS)中指定的相同。Win32 API函數的輸出名可能不一樣於你在代碼中調用的這些函數名,這個不一樣被宏隱含在相關的SDK頭文件中。若是想獲得更多信息,請參考Win32函數原型(Win32 Function Prototypes)。
lpProcName參數可以識別DLL中的函數,經過指定一個與函數相聯繫的序數值(在.DEF中的EXPORTS段)。GetProcAddress函數驗證那個指定的序數值是否在輸出的序數1和最高序數值之間(在.DEF中)。函數用這個序數值做爲索引從函數表中讀函數地址,假如.DEF 文件不連續地定義函數的序數值,如從1到N(N是輸出的函數序數值),錯誤將會發生,GetProcAddress將會返回一個錯誤的、非空的地址,雖然指定的序數沒有對應的函數。
爲了防止函數不存在,函數應該經過名字指定而不是序數值。
要求:
Windows NT/2000: 要求 Windows NT 3.1  或之後版本。
Windows 95/98: 要求Windows 95 或之後版本。
頭文件: 在Winbase.h中聲明,include Windows.h。
庫文件: Use Kernel32.lib。

1.3 參考代碼

動態連接庫縱覽( Dynamic-Link Libraries  Overview), 動態連接庫函數(Dynamic-Link Library Functions),FreeLibrary, GetModuleHandle, LoadLibrary
示例代碼:
調用KERNEL32.DLL中的RegisterServiceProcess(僅在Windows98中適用)
HMODULE hModule=GetModuleHandle("kernel32.dll");
if (hModule)
  {
  typedef DWORD (CALLBACK *LPFNREGISTER)(DWORD,DWORD);
  LPFNREGISTER lpfnRegister;
  lpfnRegister=(LPFNREGISTER)GetProcAddress(hModule,"RegisterServiceProcess");
  if (lpfnRegister)
  {
  (*lpfnRegister)(NULL,1L);
  }
  }

 2 LoadLibrary()

HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);
Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
載入指定的 動態連接庫,並將它映射到當前進程使用的 地址空間。一旦載入,便可訪問庫內保存的資源
Long,成功則返回庫模塊的句柄,零表示失敗。會設置GetLastError
參數 類型及說明
lpLibFileName String,指定要載入的 動態連接庫的名稱。採用與CreateProcess函數的lpCommandLine參數指定的一樣的搜索順序
註解
一旦不須要,用FreeLibrary函數釋放DLL

3 FreeLibrary()

Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count. When the reference count reaches zero, the module is unloaded from the address space of the calling process and the handle is no longer valid. 函數

3.1 函數原型

BOOL WINAPI FreeLibrary(
  _In_  HMODULE hModule
);
this

 Parameters
hModule  [in]

A handle to the loaded library module. The LoadLibrary, LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function returns this handle. spa

Return value 指針

If the function succeeds, the return value is nonzero. orm

If the function fails, the return value is zero. To get extended error information, call the GetLastError function. htm

3.2 註釋

The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary. The reference count is also incremented by a call to LoadLibraryEx unless the module is being loaded for the first time and is being loaded as a data or image file. 索引

The reference count is decremented each time the FreeLibrary or FreeLibraryAndExitThread function is called for the module. When a module's reference count reaches zero or the process terminates, the system unloads the module from the address space of the process. Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process. 進程

It is not safe to call FreeLibrary from DllMain. For more information, see the Remarks section in DllMain. 資源

Calling FreeLibrary does not affect other processes that are using the same module.

Use caution when calling FreeLibrary with a handle returned by GetModuleHandle. The GetModuleHandle function does not increment a module's reference count, so passing this handle to FreeLibrary can cause a module to be unloaded prematurely.

A thread that must unload the DLL in which it is executing and then terminate itself should call FreeLibraryAndExitThread instead of calling FreeLibrary and ExitThread separately. Otherwise, a race condition can occur. For details, see the Remarks section of FreeLibraryAndExitThread.

相關文章
相關標籤/搜索