如何動態地載入動態連結程式庫 (DLL) 在 Windows NT 中

文章翻譯 文章翻譯
文章編號: 100635 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

結論

當您使用 LoadLibrary() 函式,在 16 位元 Windows 或在 OS/2 時, 在作業系統載入指定的動態連結程式庫 (DLL) 只有一次。因此,DLL 在每個處理程序中有相同的地址。不過,動態載入的 DLL 運作以不同方式在 Windows NT。

在作業系統載入分別為每個處理程序的 DLL,因為每個應用程式具有自己的位址空間,在 Windows NT 中 ; 在 16 位元 Windows 和 OS/2 共用的位址空間。 因為作業系統必須將頁面對應至位址空間,以讓每個處理程序,DLL 可能會被載入在不同的地址在不同處理序中。 記憶體管理員會最佳化載入 DLL,因此如果兩個處理序共用相同的頁面,從相同的 DLL 影像,它們會共用相同的實體記憶體。

每個 DLL 有慣用的基底位址,在連結階段指定。如果無法使用地址空間範圍從慣用的基底位址到基本位址加上影像大小,作業系統會載入記憶體中其他地方 DLL,並將修復套用至它的位址。沒有方法來指定在載入時間的載入位址。

合併彙算,系統會在載入時間,執行下列步驟:
  1. 檢查該影像,並決定其慣用的基底位址以及所需的大小。
  2. 尋找所需的位址空間,並將對應影像上, 寫入複製,從檔案]。
  3. 如果影像不在其慣用的基底位址,會套用內部的修復。
  4. 修正所有的動態連結匯入了藉由將每個匯入函式正確的地址放入適當的匯入位址資料表的項目。此表格會連續地儲存 32 位元位址,來儲存最多 1024 個匯入函式需要用它骯髒的只有一個記憶體分頁。

其他相關資訊

被共用在使用寫入時複製保護配置頁面,其中包含程式碼。寫入時複製表示頁面是唯讀 ; 不過,如果處理程序將寫入至頁面和存取違規不會發生。 改,記憶體管理員會為應用程式的使用頁面的私用複本,並允許繼續進行寫入。比方說如果兩個處理序啟動從相同的.EXE 檔,每個處理程序一開始會有 [.EXE 檔上寫入複製從對應的所有網頁。兩個處理序進行修改的網頁時, 每一個接收私用的網頁的複本。記憶體管理員可以自由最佳化未經修改的頁面,並對應相同的實體記憶體位址空間中的兩個處理程序。與網頁檔案,而不是.EXE 檔交換修改過的網頁。

兩種修復類型為可用。第一個用於匯入函式的位址。 根據到可攜式可執行檔] 規格的修復這個型別會儲存在匯入位址資料表 (IAT) 的另一個則用於每個匯入函式的 32 位元函式指標陣列。[IAT 有它自己的頁面,因為它永遠會修改。匯入函式呼叫是實際間接呼叫透過 [IAT 中適當的項目。當影像在其慣用的基底位址載入時,匯入函式的修復是唯一的修復所需。

請注意最佳化因素是可用 whereby 每個匯入程式庫將 32 位元的數字對應匯出與每個函數中,除了任何名稱或序數編號。這修復執行於載入時間的速度來當做提示 」。如果在應用程式和載入的 DLL 中提示不符合,載入器會執行二進位搜尋根據函式名稱。

影像影像時的資料載入某處其他比其慣用的基底地址或其他修復型別是必要的程式碼的參考。當記憶體管理員會從記憶體移除網頁時,它會檢查以查看頁面的已被修改。如果不,頁面會保留它的寫入時複製對應,並從記憶體捨棄。否則,它必須被寫入才能分頁檔案以便從分頁檔,而不是從可執行檔映像檔案復原已修改的頁面。

即使應用程式 DLL 的不只一次呼叫 LoadLibrary(),DLL 的進入點 DllMain(),呼叫僅一次,而且建立只有一個 DLL_PROCESS_ATTACH 項目。同樣地,如果應用程式會呼叫 FreeLibrary() 超過一次 DLL_PROCESS_DETACH 只發生在呼叫的 DLL 參考計數傳回為零。

為 DLL 的全域執行個體資料會儲存每個處理程序為基本來 (只有一個資料集每個處理程序)。 如果是儲存在一個處理程序中執行每個 LoadLibrary() 呼叫的全域執行個體資料的必要請考慮使用執行緒區域儲存區 (TLS) 另一種方法。如果您使用 [多執行緒的執行 TLS 會提供唯一的資料儲存為每個 ThreadID 值。這個程序為 DLL 需要極少負荷 ; 它只必須建立全域的 TLS 索引在處理序初始化。在執行緒初始化使用 [GlobalAlloc()HeapAlloc()LocalAlloc(),C 執行階段程式庫或另一個方法來配置的記憶體區塊,並呼叫 TlsSetValue() 函式,以儲存的指標,使用全域 TLS 記憶體中的函式索引值。Win32 內部儲存由 TLS 索引,以及提供特定執行緒的儲存體 ThreadID 索引的每個執行緒的指標。

屬性

文章編號: 100635 - 上次校閱: 2005年12月9日 - 版次: 5.0
這篇文章中的資訊適用於:
  • Microsoft Visual C++ 1.0 Professional Edition
  • Microsoft Visual C++ 2.0 Professional Edition
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Visual C++ .NET 2002 Standard Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft Visual C++ 2005 Express Edition
關鍵字:?
kbmt kbdll kbhowto kbinfo kblangc KB100635 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:100635
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com