1. 程式人生 > >dll和lib關系及使用

dll和lib關系及使用

分享圖片 pen 查找 rar 例子 兩個 變量 註意 圖片

對於dll和lib兩者的關系,需要理解的一個概念是編譯時和運行時。

lib是編譯時的東西,在lib裏面包含了方法名和方法所在的dll名字,可以用dumpbin -all XXX.lib查看內容。 dll是運行時的東西,裏面是方法的實體。可以通過depends查看裏面的方法和引用的dll文件等。

舉個例子方便理解: 有兩個project,A和B,A的輸出是一個動態dll,B的輸出是一個exe。B需要用到A裏面的類和方法等。

首先是對A的處理:要把A的類或方法定義為“導出型”,即使用關鍵字_declspec(dllexport)。 如把一個類定義為導出類:class _declspec(dllexport) BaseTool{} 並且在A的project裏面把配置類型設為dll動態庫,編譯完畢的時候可以看到A.dll和A.lib兩個文件。可以把A.dll和A.lib輸出到兩個不同的目錄下。如下圖所示:在“常規”->“輸出目錄”這邊設置輸出lib的文件夾,在“鏈接器”->"常規"->"輸出文件"這邊設置輸出的dll文件,註意一個是文件夾,一個是文件。 技術分享圖片
圖1 技術分享圖片 圖2

編譯完成之後,可以在指定的目錄下面找到.lib和.dll。

對於B,也需要一系列的處理:

首先是頭文件,需要把A裏面對於類定義的頭文件夾放到項目屬性中的包含目錄下,如下圖:

技術分享圖片

圖3

這裏面發現了一個比較有意思的事情,原先我以為只要把頭文件加到solution欄裏面的項目頭文件處就可以了(如下圖),項目就會自動包含進來。沒想到不是這樣子的,關鍵還是在上圖的包含目錄裏面加入頭文件所在的文件夾路徑,下圖解決方案裏面的可能只是方便開發人員打開頭文件設置的,加不加不影響編譯和運行。

技術分享圖片

圖4

其次是附加庫目錄和附加依賴項:

技術分享圖片

圖5

技術分享圖片

圖6

附加庫目錄也可以通過圖3中的‘庫目錄’替代,兩者效果一樣。

附加依賴項是包含所需要的lib文件,可以指定全路徑,也可以只是指定名字,當只指定名字的時候,系統會在附加庫目錄或者庫目錄裏面搜尋。如果不指定附加依賴項,也可以通過在代碼裏面加入#pragma comment(lib,"XXX.lib")來實現。

到此為止,編譯應該是可以過了,但是具體運行的時候,會報出找不到dll的錯誤,這就是運行時錯誤了。 用dumpbin -all A.lib並重定向到一個txt文件中,可以看到lib裏面有提到方法屬於哪個dll,因此需要讓它知道在哪裏查找dll。 這時是運行時的事情了,需要設置系統環境變量,把dll所在目錄加進去就可以了。如果是debug模式,需要重啟VS。 其實lib文件可以不需要,而直接調用dll裏面的方法。 采用LoadLibrary和GetProcAddress的方法,那樣子可以不需要lib文件。但是有一個重大影響,就是得知道方法名的準確名字。特別是對於c++輸出整個類的情形。因為c++輸出dll的時候,類的方法名都被打亂了,加入了很多的信息,所以一般情況下是不知道的,得通過def文件來重命名輸出的方法名。

dll和lib關系及使用