在 windows 的系統目錄中,存在著很多的動態鏈結庫檔案(dll 檔案)。這些 dll 檔案中包括了 windows api 函式可執行程式。
dll 將各函式"匯出",這樣應用程式就可以找到 dll 中的函式位址,當應用程式呼叫 windows api 時,程式會執行到 dll 中的函式。
api 函式主要存在於幾個核心的動態連線庫檔案中。
kernel32.dll:
kernel32.dll 包括了系統基本服務中最基本的 api 函式,如檔案系統、程序與執行緒、記憶體管理等。windows xp sp2 系統中,kernel32.dll 有 949 個匯出函式,例如,createfilea、createprocessa、openthread、setfiletime 等。本書將在後續章節中通過例項介紹這些 api 的使用。
user32.dll:
user32.dll 是 windows 圖形使用者介面的主要支援。一些重要的圖形使用者介面函式由 user32.dll 函式匯出。windows xp sp2 系統中,user32.dll 有 732 個匯出函式,例如 createwindowexw、registerclassa 等。
gdi32.dll:
gdi32.dll 是 windows gdi 應用程式設計介面,gdi32.dll 匯出了與此相關的若干函式,如 gettextcolor、lineto、textouta 等。
使用dll:
載入dll分為兩種方式:
getprocessaddress()
1、先建立了靜態鏈結庫的專案
標頭檔案**如下:
#ifdef __cplusplus
#define export extern "c" __declspec(dllexport)
#else
#define export __declspec(dllexport)
#endif
// 在標頭檔案中根據編譯器來進行判斷,之後方便原始檔處理
// extern "c" __declspec(dllexport) 以c語言的規則匯出函式,並且
// 如果是c語言來寫 就不需要寫 extern "c"
//標頭檔案中函式的宣告
export bool callback edrcentertexta(hdc hdc,prect prc,pcstr pstring);
export bool callback edrcentertextw(hdc hdc, prect prc, pcwstr pstring);
//編碼判斷
#ifdef unicode
#define editcentertext edrcentertextw
#else
#define editcentertext edrcentertexta
#endif
原始檔**如下:
// dll1.cpp : 定義 dll 應用程式的匯出函式。
//#include "stdafx.h"
#include "dll1.h"
int winapi dllmain(hinstance hinstance, dword fdwreason, pvoid pvreserved)
export bool callback edrcentertexta(hdc hdc, prect prc, pcstr pstring)
export bool callback edrcentertextw(hdc hdc, prect prc, pcwstr pstring)
然後進行編譯,把生成的.lib
和.dll
檔案放到我們寫的win32程式的目錄中
在win32中需要包含上方的.h
標頭檔案,然後在視窗過程的**函式wm_paint中新增如下**:
case wm_paint:
還需要在win32專案中新增.lib
依賴項,再生成檔案執行
缺點:
1、生成的可執行檔案體積大
2、當多個程式執行時候需要多次包含相同的公共**,造成浪費
答:其實不是的,kernel32.dll在核心中,物理頁上只有乙份,當乙個程序啟動呼叫kernel32.dll的時候是通過對映
的方式進行呼叫的,從而節省了資源
具體的大家可以參考:
1、dll專案檔案**如下:
標頭檔案**:
#ifdef __cplusplus
#define export extern "c" __declspec (dllexport)
#else
#define export __declspec (dllexport)
#endif
export dword demoa();
export dword demow();
#ifdef unicode
#define demo demow
#else
#define demo demoa
#endif
dllmain檔案如下:
// dllmain.cpp : 定義 dll 應用程式的入口點。
#include "stdafx.h"
#include "dll2.h"
bool apientry dllmain( hmodule hmodule,dword ul_reason_for_call,lpvoid lpreserved)
return true;
}export dword demoa()
export dword demow()
2、建立乙個mfc的專案,建立三個按鈕,實現**如下:
動態鏈結庫呼叫dll分為6步走
1、宣告函式指標typedef dword(*mydemow)();
2、定義函式指標變數mydemow demo =
3、動態載入dll到記憶體hmo = loadlibrary(_t("dll2.dll"));
4、函式指標變數接收dll中載入函式的位址mydemow demo= (mydemow)getprocaddress(hmo, "demow")
5、呼叫函式指標demo();
6、釋放動態鏈結庫freelibrary(hmo);
hmodule hmo;
typedef dword(*mydemow)();
void cdllmfcdlg::onbnclickedbutton1()
void cdllmfcdlg::onbnclickedbutton2()
void cdllmfcdlg::onbnclickedbutton3()
dll檔案需要和mfc編譯的exe檔案放在一起
執行效果
模組定義檔案:
關於def定義介紹可以查詢微軟的官方文件:
1、有無函式名稱
2、有無函式編號
例如跟上面一樣定義了4個函式,加減乘除:
當定義了def檔案之後就不需要去宣告匯出函式了,也就是不需要再加extern "c" _declspec(dllexport) `
然後定義的dll.def
,名稱任意但是需要字尾為def,內容如下:
exports
plus @11
sub @12
div @14
mul @15 noname
編譯,檢視其匯出表,內容如下:
sub函式被隱藏了名稱
好處:有一定的保護程式的作用!
靜態載入dll和動態載入dll
一,首先編寫dll 建win32空dll工程 標頭檔案.h extern c declspec dllexport int max int a,int b extern c 解決函式名由於不同編譯器造成的名字匹配問題,通常c 編譯器編譯時會對函式進行改名,而c編譯器不會 extern c decls...
靜態載入dll和動態載入dll
一,首先編寫dll 建win32空dll工程 標頭檔案.h extern c declspec dllexport int max int a,int b extern c 解決函式名由於不同編譯器造成的名字匹配問題,通常c 編譯器編譯時會對函式進行改名,而c編譯器不會 extern c decls...
VC靜態載入DLL和動態載入DLL
a.dll 和a.lib 兩個檔案都有的話可以用靜態載入的方式 message 函式的宣告你應該知道吧,把它的宣告和下面的語句寫到乙個標頭檔案中 pragma comment lib,a.lib 然後你的對話方塊 cpp 中包含這個標頭檔案就可以使用 message 函式了。如果dll 沒有對應的 ...