靜態鏈接庫VS動態鏈接庫
靜態鏈接庫與動態鏈接庫都是共享代碼的方式。
靜態鏈接庫
- 包含:頭文件 .h 、靜態庫 .lib
- .lib包含了實際執行代碼、符號表等等。
- .lib中的指令都全部被直接包含在最終生成的 EXE 文件中。
- 靜態鏈接庫中不能再包含其他的動態鏈接庫或者靜態庫。
- 對函數庫的鏈接是放在編譯時期完成的。
- 程序在運行時與函數庫沒有瓜葛,移植方便。
- 浪費空間和資源。
動態鏈接庫
- 包含:頭文件 .h 、導入庫 .lib 、動態庫 .dll
- 其實際的執行代碼位於.dll中,.lib只包含了地址符號表等,確保程序找到對應函數的一些基本地址信息。
- .dll不必被包含在最終exe文件中,exe文件執行時可以“動態”地引用和卸載這個與 exe獨立的dll文件。
- 動態鏈接庫中還可以再包含其他的動態或靜態鏈接。
- 將庫函數的鏈接載入推遲到程序運行時期。
- 可以實現進程間的資源共享(因此也稱爲共享庫)。
- 將一些程序升級變得簡單。
- 可以真正的做到鏈接載入完全由程序員在程序代碼中控制(顯示調用)。
靜態鏈接庫的生成
關鍵點:配置類型 –> 靜態庫(.lib)
具體方法如下:
新建一個工程
創建頭文件:staticTest.h
int add(int a,int b);
- 創建源文件:staticTest.cpp
#include "staticTest.h"
int add(int a,int b){
return a+b;
}
修改配置類型屬性,注意編譯時配置的屬性(debug還是release,win32還是win64)決定生成的庫文件是什麼類型。
編譯,生成的 myStaticLibTest.lib 庫文件位於解決方案的debug或release文件夾中。
靜態鏈接庫的使用
調用方法一
- 創建新項目,將庫文件 myStaticLibTest.lib 和 staticTest.h 頭文件copy到項目目錄下(存放源文件的地方)
- 創建源文件:testLib.cpp
#include "staticTest.h" //包含頭文件
#pragma comment(lib, "myStaticLibTest.lib") //連接庫文件
#include<stdlib.h>
#include<stdio.h>
#define namespace std;
void main(int argc, char* argv[]){
printf("a+b=%d\n",add(1,2));
system("pause");
}
注意:myStaticLibTest.lib 和 staticTest.h也可以放到別的地方,只需要在程序中加上相對或絕對路徑即可,如:”../myLib/myStaticLibTest.lib”(”.”指同級目錄,”..”指上一級目錄)
調用方法二
- 創建新項目,將庫文件 myStaticLibTest.lib 和 staticTest.h 頭文件copy到”solution/mylib”(可隨意指定)目錄下。
指定頭文件所在目錄:包含目錄,庫文件所在目錄:庫目錄(可寫相對或絕對路徑)。
添加鏈接庫:附加依賴項
創建源文件:testLib.cpp
#include "staticTest.h" //包含頭文件
#include<stdlib.h>
#include<stdio.h>
#define namespace std;
void main(int argc, char* argv[]){
printf("a+b=%d\n",add(1,2));
system("pause");
}
動態鏈接庫的生成
關鍵點:配置類型 –> 動態庫(.dll)
具體方法如下:
- 新建一個工程:myDynamicLibTest
- 創建頭文件:dynamicTest.h
/***************
下面一段的作用是使"生成dll的項目"和"調用dll的項目"都可以使用同一個頭文件:dynamicTest.h 。
__declspec(dllexport),生成dll的項目用於導出(函數 變量 類等)。
導出變量: __declspec(dllexport) int a;
導出函數: __declspec(dllexport) void a();
導出類 : class __declspec(dllexport) a{};
__declspec(dllexport),調用dll的項目中用於導入(函數 變量 類等)。
***************/
#ifdef DLL_EXPORTS
#define MYDLL_EXPORT __declspec(dllexport)
#else
#define MYDLL_EXPORT __declspec(dllimport)
#endif
MYDLL_EXPORT int add(int a,int b);//顯示調用最好在前頭加上extern “C” 變爲C標準編譯,可杜絕C++的重載
- 創建源文件:dynamicTest.cpp
//DLL_EXPORT宏定義要位於包含dynamicTest.h之前,這個宏也可以在預處理器中添加,如下圖。
#define DLL_EXPORTS
#include "dynamicTest.h"
int add(int a,int b){
return a+b;
}
- 修改配置類型屬性,注意編譯時配置的屬性(debug還是release,win32還是win64)決定生成的庫文件是什麼類型。
- 編譯,生成的 myStaticLibTest.lib 和 myStaticLibTest.dll 文件位於解決方案的debug或release文件夾中。
動態鏈接庫的使用
動態鏈接庫的使用和靜態鏈接庫類似,唯一不同的是需要將myStaticLibTest.dll文件和項目編譯生成的執行文件:.exe文件放在一起,一般位於解決方案的debug或release文件夾中。