2017-02-17 44 views
-1

我聽說導入庫有「存根」,所以可執行文件知道我們想要哪個dll和函數。現在我的問題是:那些存根是什麼?他們看起來怎麼樣?可執行文件如何將指針設置爲DLL中的正確位置?它是如何知道我們是否在談論普通庫或導入庫,因爲它們都是.lib文件?導入庫如何工作?

+0

另請參閱https://msdn.microsoft.com/en-us/magazine/bb985992.aspx –

+0

可執行文件不知道這些。它是鏈接器,它會發出適當的代碼。 – IInspectable

回答

1

MSVC鏈接器不直接鏈接到DLL,它只能鏈接到靜態庫(.lib)。

非常粗略地說,一個導入庫是一個正常的靜態庫,對每個DLL導出的函數都有一個存根函數。

例如,如果一個DLL具有的功能void func1()和出口func1,相應的導入庫將包含存根函數void __imp__func1() { __asm { jmp dword ptr func1; } }

在運行時,「跳」將採取func1地址從導入表。這就是爲什麼需要存根。

申請中的聲明void __declspec(dllimport) func1();實際上是指__imp__func1()

您可以繞過這整個機制,並在運行時撥打LoadLibraryGetProcAddress以獲取地址func1。它會有同樣的效果。

1

這取決於您使用的編譯器(鏈接器)和平臺。

I.e.在Windows操作系統上,共享庫通常是.DLL文件,如果要鏈接到它(除了動態加載它並在運行時解析其符號),則需要相應的.LIB文件,即存根庫。

基本上存根庫是重新映射由DLL輸出(與__declspec(dllexport))的所有符號中存在的存根和,可以發現,通過使用__declspec(dllimport)程序內的靜態鏈接符號的靜態庫。

+0

那麼__declspec(dllexport)是來自Windows API的函數,還是Visual Studio中的指令? –

+0

@Daniel Nyman:'__declspec'是一個關鍵字(據我所知,特定於Visual Studio),'dllexport'和'dllimport'是該關鍵字的屬性。更多信息,請訪問:https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx – roalz

+0

[__declspec](https://msdn.microsoft.com/en-us/library/dabb5z75.aspx)是一個關鍵字,它分配一個Microsoft特定的存儲類屬​​性。 – IInspectable