VS2013生成DLL文件html
通常來講項目偏心生成dll動態庫文件,由於能夠解決靜態庫形成的空間浪費和更新困難問題,另外建立靜態庫時,我通常是創建空項目後,在項目配置類型中進行選擇。程序員
什麼是庫github
庫是寫好的現有的,成熟的,能夠複用的代碼。現實中每一個程序都要依賴不少基礎的底層庫,不可能每一個人的代碼都從零開始,所以庫的存在乎義非同尋常。本質上來講庫是一種可執行代碼的二進制形式,能夠被操做系統載入內存執行。庫有兩種:靜態庫(.a、.lib)和動態庫(.so、.dll)。windows
所謂靜態、動態是指連接。回顧一下,將一個程序編譯成可執行程序的步驟:函數
靜態庫ui
之因此稱爲【靜態庫】,是由於在連接階段,會將彙編生成的目標文件.o與引用到的庫一塊兒連接打包到可執行文件中。所以對應的連接方式稱爲靜態連接。spa
試想一下,靜態庫與彙編生成的目標文件一塊兒連接爲可執行文件,那麼靜態庫一定跟.o文件格式類似。其實一個靜態庫能夠簡單當作是一組目標文件(.o/.obj文件)的集合,即不少目標文件通過壓縮打包後造成的一個文件。操作系統
靜態庫優缺點總結:.net
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的項目所使用。dllexport和dllimport存儲類特性是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:最好不要用這個)
以上皆能夠自由組合。
-------------------------------------------------------------------------------------------
歡迎訪問圖像計數項目總結:基於圖像處理的毛氈墊計數項目總結
Github地址:Extract-inner-image
yolo-windows項目開源代碼:LargeImageDetect-yolo-windows