VS2013生成、使用dll,lib文件


VS2013生成DLL文件

vs2013創建及使用DLL

  一般來說項目偏愛生成dll動態庫文件,因為可以解決靜態庫造成的空間浪費和更新困難問題,另外創建靜態庫時,我一般是建立空項目后,在項目配置類型中進行選擇。

什么是庫

  庫是寫好的現有的,成熟的,可以復用的代碼。現實中每個程序都要依賴很多基礎的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常本質上來說庫是一種可執行代碼的二進制形式,可以被操作系統載入內存執行。庫有兩種:靜態庫(.a、.lib)和動態庫(.so、.dll)。

  所謂靜態、動態是指鏈接。回顧一下,將一個程序編譯成可執行程序的步驟:

靜態庫

  之所以稱為【靜態庫】,是因為在鏈接階段,會將匯編生成的目標文件.o與引用到的庫一起鏈接打包到可執行文件中。因此對應的鏈接方式稱為靜態鏈接。

  試想一下,靜態庫與匯編生成的目標文件一起鏈接為可執行文件,那么靜態庫必定跟.o文件格式相似。其實一個靜態庫可以簡單看成是一組目標文件(.o/.obj文件)的集合,即很多目標文件經過壓縮打包后形成的一個文件。

靜態庫優缺點總結:

  1. 靜態庫對函數庫的鏈接是放在編譯時期完成的。

  2. 程序在運行時與函數庫再無瓜葛,移植方便。

  3. 浪費空間和資源,因為所有相關的目標文件與牽涉到的函數庫被鏈接合成一個可執行文件。

Windows下創建與使用靜態庫

創建靜態庫(.lib)

  創建靜態庫有兩種方法。

  (1)創建項目時進行設置

  創建win32控制台程序時,勾選靜態庫類型(下面的預編譯等選項可選可不選);打開工程“屬性面板”-”配置屬性”-”常規”,配置類型選擇靜態庫。

  (2)生成項目時進行設置

  創建空項目之后,生成項目時,選擇項目-屬性-配置屬性-常規-項目默認值-配置類型-選擇生成靜態庫lib。

  程序編譯通過后,Build項目即可生成靜態庫。即可生成.lib,輸出欄會顯示出靜態庫的位置。

拷貝到工程目錄下

  右擊項目 - 在文件資源管理器中打開文件夾 - 將文件拷貝至工程目錄下

使用靜態庫

  如果將靜態鏈接庫和頭文件拷貝到工程目錄下,則可以只進行這一步:“屬性面板”-”配置屬性”-“鏈接器”-”輸入”,附加依賴庫中輸入靜態庫名StaticLibrary.lib,或者采用以下語句:

 1 #pragma comment(lib, "./StaticLibrary.lib"); 

  如果沒有進行拷貝,則需要通過“屬性面板”-”配置屬性”-“VC++目錄”-”庫目錄”,將路徑添加到工程中,另外在附加依賴庫目錄中輸入靜態庫所在目錄。

 

動態庫

  通過上面的介紹發現靜態庫,容易使用和理解,也達到了代碼復用的目的,那為什么還需要動態庫呢?

為什么還需要動態庫(靜態庫的缺點)?

  為什么需要動態庫,其實也是靜態庫的特點導致。

  1.空間浪費是靜態庫的一個問題。

  2.另一個問題是靜態庫對程序的更新、部署和發布也會帶來麻煩。如果靜態庫lib更新了,所有使用它的應用程序都需要重新編譯、發布給用戶(對於玩家來說,可能是一個很小的改動,卻導致整個程序重新下載,全量更新)。

  動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行時才被載入不同的應用程序如果調用相同的庫,那么在內存里只需要有一份該共享庫的實例,規避了空間浪費問題。動態庫在程序運行時才被載入,也解決了靜態庫對程序的更新、部署和發布頁會帶來麻煩。用戶只需要更新動態庫即可,增量更新

 

  動態庫特點總結

  1.動態庫把對一些庫函數的鏈接載入推遲到程序運行的時期。

  2.可以實現進程之間的資源共享。(因此動態庫也稱為共享庫)

  3.將一些程序升級變得簡單。

  4.甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制(顯示調用)。

Windows下創建與使用動態庫

創建動態庫(.dll)

  創建動態庫同樣有兩種方法,創建前設置和生成項目時設置。

  (1)創建前設置

  創建前設置步驟如下:單擊“新建項目”,選擇“Win32 項目”,選擇“下一步”,然后到了如下界面:點擊“DLL”,並同時點擊“導出符號”。然后點擊“完成”。“導出符號”,將為我們創建生成DLL的模板。仔細觀察,vs自動為我們創建了示例,導出變量nMakeDLL,導出函數fnMakeDLL和導出類CMakeDLL。如果上面沒有點擊“導出符號”,將不會生成這些。所以為了方便DLL的創建,我們最好還是使用“導出符號”。

  先看下面這段代碼:

1 #ifdef MAKEDLL_EXPORTS
2 
3 #define MAKEDLL_API __declspec(dllexport)
4 
5 #else
6 
7 #define MAKEDLL_API __declspec(dllimport)
8 
9 #endif

  如果定義了MAKEDLL_EXPORTS,然后我們再定義MAKEDLL_API為__declspec(dllexport),否則我們定義__declspec(dllimport)。前者主要為生成DLL的項目所使用,后者為使用DLL的項目所使用。dllexportdllimport存儲類特性是C和C++語言的Microsoft專用擴展。可以使用它們從 DLL 中導出或向其中導入函數、數據和對象。

  為什么要使用__declspec(dllexport)與__declspec(dllimport),及兩者的區別:都是DLL內的關鍵字,即導出與導入。他們是將DLL內部的類與函數以及數據導出與導入時使用的。主要區別在於,dllexport是在這些類、函數以 及數據的申明的時候使用。用過表明這些東西可以被外部函數使用,即(dllexport)是把DLL中的相關代碼(類,函數,數據)暴露出來為其他應用程 序使用。使用了(dllexport)關鍵字,相當於聲明了緊接在(dllexport)關鍵字后面的相關內容是可以為其他程序使用的。而 dllimport關鍵字是在外部程序需要使用DLL內相關內容時使用的關鍵字。當一個外部程序要使用DLL內部代碼(類,函數,全局變量)時,只需要在 程序內部使用(dllimport)關鍵字聲明需要使用的代碼就可以了,即(dllimport)關鍵字是在外部程序需要使用DLL內部相關內容的時候才使用。(dllimport)作用是把DLL中的相關代碼插入到應用程序中。如果沒有使用dllexport導出函數,將無法生成lib文件,只能生成dll文件。

  接下來,你可以改寫上面的類和函數,然后點擊項目,選擇“生成”即可產生DLL和LIB。為了簡化起見,本例只考慮導出函數。

  修改完成后點擊Build項目,在輸出欄顯示dll文件的生成位置。

  (2)生成項目時設置

  這種方法要求生成動態庫需要設置工程屬性,打開工程“屬性面板”-”配置屬性”-”常規”,配置類型選擇動態庫。但這種方法是建立空項目,因此,需要在頭文件中手動設置__declspec(dllexport)等語句。

  可以直接使用上面那段代碼,也可以只在導出的函數前加__declspec(dllexport),注意:前面是兩條下划線

  生成的DLL文件如下圖所示:

  這里可能大家有個疑問,動態庫怎么還有一個DynamicLibrary.lib文件?即無論是靜態鏈接庫還是動態鏈接庫,最后都有lib文件,那么兩者區別是什么呢?其實,兩個是完全不一樣的東西。

 

  StaticLibrary.lib的大小為190KB,DynamicLibrary.lib的大小為3KB,靜態庫對應的lib文件叫靜態庫,動態庫對應的lib文件叫導入庫。實際上靜態庫本身就包含了實際執行代碼、符號表等等,而對於導入庫而言,其實際的執行代碼位於動態庫中,導入庫只包含了地址符號表等,確保程序找到對應函數的一些基本地址信息

使用動態庫

  在引用一個新的dll時,我們一般需要dll的.h,.lib和.dll三個文件。

  將三個文件拷貝到工程目錄下,對於lib和頭文件的使用方法與靜態鏈接庫相同,這時直接運行程序,可能會出現一個錯誤,說“缺少什么dll”,我們只需將此前生成的dll,放在debug或release目錄下,即可編譯通過。

 

使用方法總結

  .h,.lib,.dll的添加方法其實各有很多種。

.h有兩種:

  1. 頭文件較少時,直接放在工程目錄下,#include "*.h"

  2. 建立include文件夾,放在里面,然后在項目屬性的“VC++目錄”-》“包含目錄”,添加.h路徑即可。

.lib的方法有兩種

  1.lib文件較少時,直接放在工程目錄下,#pragma comment(lib, "testCpp.lib")

  2.建立lib文件夾,目屬“VC++目錄”-》“庫目錄”添加路徑,然后在項目屬性的“鏈接器”-》“輸入”-》“附加依賴項”,添加.lib名字。

dll的方法有兩種

  1.直接放在debug/release目錄下

  2.建立bin文件夾,放在里面,然后在項目“環境”中添加bin的路徑(PS:最好不要用這個)

  以上皆可以自由組合。 

-------------------------------------------------------------------------------------------------

如果上面的資料對你有啟發,麻煩點個推薦,讓更多人的人看到哦。

關注公眾號【兩猿社】,懂點互聯網,懂點IC的程序猿,帶你豐富項目經驗哦

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM