2009-09-10 24 views
0

我無法獲得有關從C++動態加載DLL文件的很多信息。 我知道它使用一些函數,如LoadLibrary和FreeLibrary與GetProcAddress。但是它是如何在操作系統透視圖的內部實際工作的,例如它實際上查找DLL文件的位置以及它像內存一樣加載的位置?有人可以用一些圖幫助我嗎?在操作系統中使用C++動態加載DLL的內部機制?

+1

這應該被標記爲操作系統相關的問題,而不是C++之一。 – 2009-09-10 12:36:12

+0

請注意,實現細節是特定於平臺的,儘管共享庫的概念對大多數平臺都很常見。你對Win32感興趣嗎? – 2009-09-10 12:36:21

+0

是的,這可能與操作系統有關,但很高興知道在英國win32 C++ – ukanth 2009-09-10 12:40:01

回答

1

DLL搜索順序上MSDN描述,並且有一個article on DLL loading,以及兩部分article describing PE formatpart two here)(他們稍微老了,但我不認爲他們是過時的)。瀏覽MSDN雜誌和MSJ檔案,你可能會發現更多。

+0

「關於DLL加載的文章」鏈接很有意思,希望對此有所瞭解。 – ukanth 2009-09-10 13:55:09

0

對於Win32,裝載程序的細節在MSDN上。見here

從你的C++代碼中,你是對的(對於Windows),你用:: LoadLibrary加載並用:: GetProcAddress解析函數指針。通常,您會將GetProcAddress的結果轉換爲您知道入口點函數的類型,然後在您的程序中使用它。例如,如果您有像瀏覽器這樣的插件體系結構,您可以決定插件目錄是什麼,獲取該目錄的文件名列表,併爲每個DLL調用:: LoadLibrary(篩選文件名將取決於你)。對於每一個,您都可以使用GetProcAddress來解析所需的入口點,將它們存儲在該庫的結構中,並將它們放入一些插件列表中。稍後,您將通過這些函數指針調用該插件來完成其工作。

如果您指定相對路徑(例如「foo.dll」而不是「c:\ foo.dll」),則OS庫搜索路徑將啓動。MSDN中的詳細信息。

此外,DLL會加載到您的進程的地址空間。通常情況下,你不關心在哪裏,但過去,通過「重新綁定」你的DLL可以獲得更快的加載時間。我不認爲OS加載程序如何將內存放置在內存中有任何保證,但您始終可以在進程的地址空間中獲取基址。

您的DLL的入口點(dllmain)也可以響應各種消息 - 線程掛接,進程掛接 - 以合理的方式進行初始化。

0

有兩種使用DLL的方法。您可以在運行時動態加載它,或者在鏈接時靜態鏈接它。

如果使用LoadLibrary動態加載,則操作系統有some mechanism to determine where to look for DLLs。然後它嘗試加載它們。然後,您可以嘗試獲取函數指針(通過字符串或普通函數)並調用這些函數。

如果鏈接是靜態的,基本上鍊接器會爲每個DLL的函數添加一個對DLL和一些跳轉表的引用。當操作系統加載應用程序時,它會查找對這些DLL的引用,嘗試加載這些DLL,並將加載的DLL函數的地址修補到跳轉表中。只有這樣,你的應用程序纔會被加載並啓動。

請注意,實際上這有點複雜。例如,DLL可以依次引用其他DLL。因此,當加載器加載DLL時,在可以考慮加載DLL之前,它需要(可能遞歸地)加載其他DLL。