在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函數獲得相應的函數。