在C/C++中經常需要用到靜態鏈接庫和動態鏈接庫。爲了瞭解什麼是靜態鏈接庫和動態鏈接庫,我們首先需要了解什麼是庫。由於經常有許多代碼需要重複利用,庫就是指創建一種文件裏面包含了很多函數和變量的目標代碼,鏈接的時候只要把這個文件指示給鏈接程序就自動地從文件中查找符合要求的函數和變量進行鏈接。而靜態鏈接庫是指目標的代碼只能進行靜態的鏈接,靜態鏈接庫的結構比動態鏈接庫簡單,只是將所有的目標代碼一起放在可執行文件中。這樣靜態鏈接庫有一個問題就是非常浪費內存,因爲如果內存中的幾個進程包含相同的鏈接庫,則代表其實有幾份相同的代碼在內存中,這其實是沒有必要的。而動態鏈接庫就是解決這個問題,動態鏈接庫的執行文件中並不包含鏈接的目標代碼,而是當執行文件載入內存時才鏈接庫。所以執行文件可以“動態”的載入鏈接庫。
生成靜態鏈接庫:
在windows中如果使用visual studio創建靜態鏈接庫的步驟是:
首先新建一個win32的工程,然後下一步時選擇靜態庫(可以預編譯頭也可以不預編譯頭),然後生成兩個文件分別是.h文件和.cpp文件。.h文件對函數進行聲明,.cpp對函數進行定義。然後生成解決方案既可以在debug文件中找到相應的lib文件,這個文件則是對應的靜態鏈接庫。
而當調用時,則需要將.h文件和相應的lib文件都拷到需要調用靜態鏈接庫的工程中(存放的位置和相應的源代碼在同一個文件夾中),在新的工程中包含.h文件,並使用#pragma comment(lib,"xxx.lib")語句包含靜態鏈接庫。
舉例說明:
在.h文件中的代碼:
- #ifndef LIB_H
- #define LIB_H
- extern "C" int exp(int a,int b);
- #endif
在.cpp文件的代碼:
- #include "static.h"
- int exp(int a,int b)
- {
- int flag = 1;
- int result = 1;
- if b < 0
- flag = -1;
- while (b)
- {
- resultresult = result * a;
- b--;
- }
- resultresult = result * flag;
- return result;
- }
新工程中的代碼:
- #include <stdio.h>
- #include <stdlib.h>
- #include "static.h"
- #pragma comment(lib,"static lib.lib")
- int main()
- {
- printf("%d\n",exp(2,6));
- system("pause");
- return 0;
- }
可以發現結果爲64。
生成動態鏈接庫:
在windows中如果使用visual studio創建動態鏈接庫的步驟是:
首先新建一個win32的工程,然後下一步 時選擇dll(可以預編譯頭也可以不預編譯頭),然後生成兩個文件分別是.h文件和.cpp文件。.h文件對函數進行聲明,.cpp對函數進行定義。然後 生成解決方案既可以在debug文件中找到相應的dll文件,這個文件則是對應的動態鏈接庫。
而當調用時,則需要將.h文件和相應的dll文件都拷到需要調用靜態鏈接庫的工程中(存放的位置和相應的源代碼在同一個文件夾中),在新的工程中包含.h文件,然後使用LoadLibrary函數和GetProcAddress函數使用動態鏈接庫。
.h文件如下:
- #ifndef LIB_H
- #define LIB_H
- extern "C" __declspec(dllexport) int exp(int a,int b);
- #endif
__declspec(dllexport)代表生成一個動態鏈接庫的導出函數。
.cpp文件與靜態鏈接庫完全一樣。
新工程中的代碼:
- #include <stdio.h>
- #include <stdlib.h>
- #include<Windows.h>
- #include "static.h"
- int main()
- {
- HINSTANCE hDll=NULL;
- typedef int(*PEXP)(int a,int b);
- PEXP pSum;
- hDll = LoadLibrary(L"dll.dll");
- pExp = (PSUM)GetProcAddress(hDll,"exp");
- printf("%d\n",pExp(2,4));
- system("pause");
- FreeLibrary(hDll);
- return 0;
- }
生成的結果爲16。首先LoadLibrary導入鏈接庫,GetProcAddress函數獲得相應的函數。
值得注意的是:如果你導入lib文件或dll文件時沒有寫路徑,則生成的exe文件需要和lib與dll文件在同一個文件夾中!!!