學習 DLL介紹以及載入DLL的兩種方法 def

2022-03-14 00:46:10 字數 4506 閱讀 1638

在 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 沒有對應的 ...