包含目錄、附加包含目錄、庫目錄、附加庫目錄、附加依賴項、動態庫、靜態庫

一、先說包含目錄

 

包含目錄 與 附加包含目錄 的區別是 檢索順序 不同。

 

The compiler searches directories in the following order:來自MSDN,一定要看英文

  1. If specified using a #include directive in double-quote form, it first searches local directories. The search begins in the same directory as the file that contains the #include statement. If this fails to find the file, it searches in the directories of the currently opened include files, in the reverse order in which they were opened. The search begins in the directory of the parent include file and continues upward through the directories of any grandparent include files.
  2. If specified using a #include directive in angle bracket form, or if the local directory search has failed, it searches directories specified by using the /I option, in the order that CL encounters them on the command line.
  3. Directories specified in the INCLUDE environment variable.

 

翻譯一下就是:

編譯器將按以下順序搜索目錄:

1.如果#include使用雙引號("")形式,它將首先搜索本地目錄。現從包含#include語句的當前文件的所在目錄開始搜索。若果失敗,則從當前目錄的父目並逐級往上搜索,直到最上層include文件所在的目錄。

2.如果#include使用尖括號(<>)形式,或者使用雙引號形式本地目錄檢索失敗,它會按照/I選項(附加包含目錄)指定的目錄搜索。順序是按照CL在命令行中遇到它們的順序。

3.INCLUDE環境變量指定的目錄,即包含目錄

 

所以,對本項目自身的#include一定要用雙引號,否則如果用尖括號,不會搜索本地目錄,而是直接從附加包含目錄開始搜索,自然就找不到本地的文件,然後報錯。至於附加包含目錄與包含目錄分別適合在什麼時候使用,還望兄弟們多多指教。

 

 

二、然後是庫目錄

 

庫目錄 與 附加庫目錄 的區別是 檢索順序 不同。

 

來自MSDN

Specifies a path that the linker will search before it searches the path specified in the LIB environment option.

 

所以,先檢索附加庫目錄,再檢索庫目錄(LIB environment option)。而且也同樣說明這兩個目錄只是制定檢索的目錄,並未說明哪些庫會被鏈接到目標文件中。想要鏈接到目標文件中,則需要在附加依賴項中指定具體的*.lib文件。然後連接器會到上邊兩個目錄搜索該lib文件。

 

三、動態庫的靜態調用和動態調用(以下信息來自

 

(1)靜態調用,也稱爲隱式調用,由編譯系統完成對DLL的加載和應用程序結束時DLL卸載的編碼(Windows系統負責對DLL調用次數的計數),調用方式簡單,能夠滿足通常的要求。通常採用的調用方式是把產生動態連接庫時產生的.LIB文件加入到應用程序的工程中,想使用DLL中的函數時,只須在源文件中聲明一下。

 

LIB文件包含了每一個DLL導出函數的符號名和可選擇的標識號以及DLL文件名,不含有實際的代碼。Lib文件包含的信息進入到生成的應用程序中,被調用的DLL文件會在應用程序加載時同時加載在到內存中。

 

(2)動態調用,即顯式調用方式,是由編程者用API函數加載和卸載DLL來達到調用DLL的目的,比較複雜,但能更加有效地使用內存,是編制大型應用程序時的重要方式。在Windows系統中,與動態庫調用有關的函數包括:

①LoadLibrary(或MFC 的AfxLoadLibrary),裝載動態庫。

②GetProcAddress,獲取要引入的函數,將符號名或標識號轉換爲DLL內部地址。

③FreeLibrary(或MFC的AfxFreeLibrary),釋放動態鏈接庫

 

四、動態庫與靜態庫區別(以下信息來自

 

靜態庫

當程序與靜態庫連接時,庫中目標文件所含的所有將被程序使用的函數的機器碼被 copy 到最終的可執行文件中。這就會導致最終生成的可執行代碼量相對變多,相當於編譯器將代碼補充完整了,優點,這樣運行起來相對就快些。不過會有個缺點: 佔用磁盤和內存空間. 靜態庫會被添加到和它連接的每個程序中, 而且這些程序運行時, 都會被加載到內存中. 無形中又多消耗了更多的內存空間。

 

動態庫

與共享庫連接的可執行文件只包含它需要的函數的引用表(lib),而不是所有的函數代碼,只有在程序執行時, 那些需要的函數代碼才被拷貝到內存中。優點,這樣就使可執行文件比較小, 節省磁盤空間,更進一步,操作系統使用虛擬內存,使得一份共享庫駐留在內存中被多個程序使用,也同時節約了內存。缺點,不過由於運行時要去鏈接庫會花費一定的時間,執行速度相對會慢一些,總的來說靜態庫是犧牲了空間效率,換取了時間效率,共享庫是犧牲了時間效率換取了空間效率,沒有好與壞的區別,只看具體需要了。

 

另外,一個程序編好後,有時需要做一些修改和優化,如果我們要修改的剛好是庫函數的話,在接口不變的前提下,使用共享庫的程序只需要將共享庫重新編譯就可以了,而使用靜態庫的程序則需要將靜態庫重新編譯好後,將程序再重新編譯一遍。這也是使用過程當中的差別。

 

五、如果想知道dll的基本原理與加載鏈接過程

請參考Windows DLL基本原理與加載連接的實現

 

參考:

MSDN:include檢索順序(中文太糟糕,請看英文)

MSDN:附加庫目錄(看英文)

dll動態調用和靜態調用有什麼區別

動態庫和靜態庫優缺點比較

Windows DLL基本原理與加載連接的實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章