標籤:共用磁碟 定義 names strong 控制台應用程式 提高 入棧 char 名稱
一、VS2013動態庫檔案的建立
1、建立項目,win32,win32項目,輸入項目名稱,例如MakeDll。
2、”確定“——”下一步“,選擇”DLL“選項,再點”完成“:
3、功能表列選擇”項目“——>”添加新項“,來建立標頭檔MakeDll.h。
在MakeDll.h中輸入以下例子代碼:
1 #ifdef DLL_API//如果已經定義就什麼都不做 2 //nothing to do 3 #else //否則定義DLL_API 4 #define DLL_API __declspec(dllexport) //_declspec(dllexport):匯出標誌 5 #endif 6 #include <iostream> 7 using namespace std; 8 DLL_API int add(int a, int b);//匯出單獨的函數 9 class DLL_API Point //匯出類,其自身所有函數都將被匯出,可單獨對某些類函數匯出10 {11 private:12 float x, y;13 public:14 Point();15 void SetPoint(float a, float b);16 void DisPlay();17 };
4、建立cpp檔案:MakeDll.cpp。
在MakeDll.cpp中輸入以下例子代碼:
1 #include "MakeDll.h" 2 3 int add(int a, int b) 4 { 5 return a + b; 6 } 7 8 Point::Point() 9 {10 x = 0.0f;11 y = 0.0f;12 }13 14 void Point::SetPoint(float a, float b)15 {16 x = a;17 y = b;18 }19 void Point::DisPlay()20 {21 cout << "x=" << x << endl;22 cout << "y=" << y << endl;23 }
5、功能表列選擇”產生——>產生解決方案“。
此時在MakeDll項目所在目錄下的Debug目錄下的檔案有MakeDll.dll和MakeDll.lib了。產生動態連結程式庫檔案OK。
二、使用剛才建立的動態庫
1、建立項目——win32控制台應用程式,命名為UseDll,並建立一個lib檔案,將MakeDll.lib引導庫放進去,
並將MakeDll.dll放進debug下,編譯器會自動搜素到這個檔案,當然可以放在系統目錄下。
2、告訴編譯器標頭檔MakeDll.h的位置(見包含目錄)、引導庫位置(見庫目錄)及其名字(見附加依賴項)。注意,以下是添加後的顯示結果。
圖.包含目錄的設定
圖.庫目錄的設定
圖.附加依賴項的設定
3、最後,動態庫的測試程式如下,測試程式需要引用標頭檔:
1 #include <iostream> 2 #include "MakeDll.h" 3 using namespace std; 4 5 int main() 6 { 7 int a = 10; 8 int b = 2; 9 int c = add(a, b);10 cout << c << endl;11 Point p1, p2;12 p2.SetPoint(5.6f, 7.8f);13 p1.DisPlay();14 p2.DisPlay();15 getchar();16 return 0;17 }
運行結果:
至此測試成功!
三、h標頭檔 .lib庫檔案 .dll動態連結程式庫檔案關係
.h標頭檔是編譯時間必須的,lib是連結時需要的,dll是運行時需要的。
附加依賴項添加的是.lib而不是.dll,若產生了DLL,則肯定也產生了LIB檔案。
.h .lib .dll三者的關係:
H檔案的作用:聲明函數介面
DLL檔案作用:函數可執行代碼
LIB檔案作用:當我們在自己的程式中引用了一個H檔案裡的函數,連結器怎麼知道該調用哪個DLL檔案呢?這就是LIB檔案的作用了。它告訴連結器調用的函數在哪個DLL中,函數執行代碼在DLL中的什麼位置,這也就是為什麼需要附加依賴項.LIB檔案,它起到橋樑的作用。
如果是產生靜態庫檔案,則沒有DLL,只有lib,這時函數可執行代碼部分也在lib檔案中。
目前以lib尾碼的庫有兩種,一種為靜態連結庫(Static Libary,以下簡稱“靜態庫”),另一種為動態串連庫(DLL,以下簡稱“動態庫”)的匯入庫(Import Libary,以下簡稱“匯入庫”)。靜態庫是一個或者多個obj檔案的打包,所以有人乾脆把從obj檔案產生lib的過程稱為Archive,即合并到一起。比如你連結一個靜態庫,如果其中有錯,它會準確的找到是哪個obj有錯,即靜態lib只是殼子。動態庫一般會有對應的匯入庫,方便程式靜態載入動態連結程式庫,否則你可能就需要自己LoadLibary調入DLL檔案,然後再手工GetProcAddress獲得對應函數了。有了匯入庫,你只需要連結匯入庫後按照標頭檔函數介面的聲明調用函數就可以了。匯入庫和靜態庫的區別很大,他們實質是不一樣的東西。靜態庫本身就包含了實際執行代碼、符號表等等,而對於匯入庫而言,其實際的執行代碼位於動態庫中,匯入庫只包含了地址符號表等,確保程式找到對應函數的一些基本地址資訊。
一般的動態庫程式有lib檔案和dll檔案。lib檔案是必須在編譯期就串連到應用程式中的,而dll檔案是運行期才會被調用的。如果有dll檔案,那麼對應的lib檔案一般是一些索引資訊,具體的實現在dll檔案中。如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。
靜態編譯的lib檔案的好處:給使用者安裝時就不需要再掛動態庫了。但也有缺點,就是導致應用程式比較大,而且失去了動態庫的靈活性,在版本升級時,同時要發布新的應用程式才行。
在動態庫的情況下,有兩個檔案,而一個是引入庫(.LIB)檔案,一個是DLL檔案,引入庫檔案包含被DLL匯出的函數的名稱和位置,DLL包含實際的函數和資料,應用程式使用LIB檔案連結到所需要使用的DLL檔案,庫中的函數和資料並不複製到可執行檔中,因此在應用程式的可執行檔中,存放的不是被調用的函數代碼,而是DLL中所要調用的函數的記憶體位址,這樣當一個或多個應用程式運行是再把程式碼和被調用的函數代碼連結起來,從而節省了記憶體資源。從上面的說明可以看出,DLL和.LIB檔案必須隨應用程式一起發行,否則應用程式將會產生錯誤。
在VC中載入LIB檔案的幾種方法:
①LIB檔案直接加入到工程檔案清單中
在VC中開啟File View一頁,選中工程名,單擊滑鼠右鍵,然後選中"Add Files to Project"菜單,在彈出的檔案對話方塊中選中要加入DLL的LIB檔案即可。
②設定工程的 Project Settings來載入DLL的LIB檔案
之前的步驟提到過,這裡不再提。
③通過程式碼的方式
加入先行編譯指令#pragma comment (lib,"*.lib"),這種方法優點是可以利用條件先行編譯指令連結不同版本的LIB檔案。因為,在Debug方式下,產生的LIB檔案是Debug版本,如Regd.lib;在Release方式下,產生的LIB檔案是Release版本,如Regr.lib。
當應用程式對DLL的LIB檔案載入後,還需要把DLL對應的標頭檔(*.h)包含到其中,在這個標頭檔中給出了DLL中定義的函數原型,然後聲明。
四、動態連結程式庫的優點
因為動態連結程式庫是將功能封裝在一起的模組,因此,與將代碼直接寫入調用模組中相比,它不僅可以提高程式的複用,減少代碼開發工作量,同時使得功能更新更方便。除了這些模組化帶來的優點外,動態連結程式庫的工作方式也決定了它先天具有比靜態連結更多的優點,如下所述。
1、節約記憶體和減少交換:當應用程式使用動態連結時,多個進程可以同步使用一個DLL共用記憶體中DLL的單個副本。相比之下,當應用程式使用靜態連結庫時,Windows必須為每個應用程式裝載一個庫代碼的副本到記憶體中。
2、節約磁碟空間:當應用程式使用動態連結時,多個應用程式可以共用磁碟上單個DLL副本。相比之下,當應用程式使用靜態連結庫時,每個應用程式要將庫代碼作為獨立的副本連結到可執行鏡像中。
3、當DLL中的函數修改時,只要函數參數、調用規定和傳回值沒有改變,使用DLL的應用程式不需要重新編譯或連結。而靜態連結的函數改變時,需要應用程式重新連結。
4、支援多語言編程:只要應用程式遵循相同的調用規範,則使用不同程式設計語言編寫的程式可以調用相同的DLL函數。程式和DLL函數必須相容:函數定義的參數入棧順序,函數或應用程式誰來負責清理堆棧,參數是否傳入寄存器中等方面必須相容。
5、輕鬆的建立中間版本:通過將資源放入DLL中,使得建立應用程式的中間版本非常簡單。如可以將應用程式的每個語言版本的字串放到單獨的一個資源DLL中,並為不同的語言版本裝載合適的資源DLL就可以了。
雖然使用DLL有諸多的優點,但是也需要格外注意使用DLL的缺點。即調用DLL的應用程式不是獨立的,程式的運行依賴於所使用的DLL是否存在。
轉自http://blog.csdn.net/ebowtang/article/details/38499927
【轉】VS2013動態庫檔案的建立及其使用詳解