《程序員的自我修養--鏈接、裝載與庫》學習筆記
動態鏈接(DLL)
DLL,即動態鏈接庫(Dynamic Link Library),在實際應用開發過程中,爲了以後對已經開發好的軟件程序進行更好的維護和管理,程序的模塊化是一個很好的管理方法,程序員大都喜歡把某一模塊的功能做成dll文件,然後導入到工程目錄中,再進行加載即可調用dll裏面的函數,大大的減少了代碼的閱讀量,節省大量的寶貴時間,如果需要對dll裏面的具體方法進行修改,直接打開生成dll文件即可,不需要在整個工程項目中查找,如果工程量較大,那查找其中某一個模塊必定是一件費時的事情。那也說明了dll/模塊化細想的重要性。
DLL加載方式
靜態加載:
- lib中的函數不僅被連接,而且全部實現都被直接包含在最終生成的EXE文件中,但是其具體實現是不可見的。
- 靜態調用中,由編譯系統完成對DLL的加載和應用程序結束時DLL的卸載:釋放已經加載的DLL模塊: FreeLibrary(hDll);
- 靜態調用:.cpp文件中包含對應的.h文件,並寫上如下語句:
#pragma comment(lib,"xxx.lib") //告訴編譯器DLL相對應的lib文件所在路徑和文件名
extern "C" _declspec(dllimport) int _stdcall Camera();//聲明導入函數
動態加載:
- dll不必被包含在最終的EXE中,動態調用時僅把函數名或者變量名或者類名鏈接到.EXE文件中,而這些東西的實體都只有在運行時才從動態庫中導入到可執行。文件中,動態調用中.EXE文件執行時可以直接動態地引用和卸載DLL文件。
- 動態調用中,由程序員用API函數加載和卸載DLL。 方式:(DLL加載—DLL函數地址獲取—DLL釋放)
DLL導入導出
- _declspec:在函數聲明類型和函數名之間加上
__declspec(dllexport) double Add(double a, double b);
__declspec(dllexport) double Sub(double a, double b);
__declspec(dllexport) double Mul(double a, double b);
extern “C” __declspec(dllexport) double Cal(double a, double b);
- .def:採用模塊定義(.def)文件聲明,需要在庫工程中添加模塊文件
LIBRARY Math
EXPORTS
Add
Sub
Mul
Cal
DLL動態加載demo
#include <windows.h>
#include <stdio.h>
typedef double (*Func)(double, double);
int main(int argc, char** argv)
{
// load dll
HINSTANCE hinstLib = LoadLibrary("Mathh.dll");
if (!hinstLib)
{
printf("ERROR: unable to load DLL\n");
return 1;
}
// get function
Func function = (Func)GetProcAddress(hinstLib, "Add");
if (!function)
{
printf("ERROR: unable to find DLL function\n");
FreeLibrary(hinstLib);
return 1;
}
// call function
double result = function(1.0, 2.0);
// unload DLL file
FreeLibrary(hinstLib);
return 0;
}