天天看點

【Windows API學習】GetProcAddress學習

顯式連結到 DLL 的程序調用 GetProcAddress 來擷取 DLL 導出函數的位址。 使用傳回的函數指針調用 DLL 函數。 GetProcAddress 将(由 LoadLibrary、AfxLoadLibrary 或GetModuleHandle 傳回的)DLL 子產品句柄和要調用的函數名或函數的導出序号用作參數。

由于是通過指針調用 DLL 函數并且沒有編譯時類型檢查,需確定函數的參數是正确的,以便不會超出在堆棧上配置設定的記憶體和不會導緻通路沖突。 幫助提供類型安全的一種方法是檢視導出函數的函數原型,并建立函數指針的比對 typedef。 例如:

typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);
...

HINSTANCE hDLL;               // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1;    // Function pointer
DWORD dwParam1;
UINT  uParam2, uReturnVal;

hDLL = LoadLibrary("MyDLL");
if (hDLL != NULL)
{
   lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
                                           "DLLFunc1");
   if (!lpfnDllFunc1)
   {
      // handle the error
      FreeLibrary(hDLL);
      return SOME_ERROR_CODE;
   }
   else
   {
      // call the function
      uReturnVal = lpfnDllFunc1(dwParam1, uParam2);
   }
}
           

調用 GetProcAddress 時指定所需函數的方式取決于 DLL 的生成方式。

僅當要連結到的 DLL 是用子產品定義 (.def) 檔案生成的,并且序号在 DLL 的 .def 檔案的 EXPORTS 部分中與函數一起列出時,才能擷取導出序号。 如果 DLL 具有許多導出函數,則相對于使用函數名,使用導出序号調用 GetProcAddress 的速度稍快一些,因為導出序号是 DLL 導出表的索引。 使用導出序号,GetProcAddress 可直接定位函數,而不是将指定名稱與 DLL 導出表中的函數名進行比較。 但是,僅當有權控制 .def 檔案中導出函數的序号配置設定時,才應使用導出序号調用 GetProcAddress。

繼續閱讀