(1)dll的構成
每個應用程式都有乙個入口函式winmain,而每個dll也有乙個入口函式dllmain。dll跟應用程式一樣都含有資源、資料段和**段。dll跟應用程式的差別主要是dll有符號輸入表和符號輸出表,以方便應用程式呼叫dll中的函式。
因為dll是由應用程式載入的,所以它本身沒有虛擬的記憶體位址空間,它使用的是載入它的應用程式的位址空間。這種載入分為隱式和顯式兩種方式。將在後面敘述。
(2)建立mfc dll
int sum(int a,int b)
int sub(int a,int b)
sum @1;
sub @2; //後面表示函式的序號
以上兩步完成後,即可編譯生成dll了,總共生成mfcdll.dll和mfcdll.lib兩個檔案。dll本身不能執行,所以還需要乙個測試程式。
c,隱式載入mfc dll並測試
用vc建立乙個對話方塊工程testdlg,加上「測試加法」「測試減法」兩個按鈕。隱式載入需要在testdlg標頭檔案頭部新增**申明:
#pragma comment(lib,"mfcdll")
int sum(int a,int b);
int sub(int a,int b);
給對話方塊按鈕新增的**如下:
void cdlltestdlg::onsum()
void cdlltestdlg::onsub()
d,顯式載入mfc dll並測試
用vc建立乙個對話方塊,放置如上的「測試加法」和「測試減法」的按鈕。採用顯式載入dll法,需要新增乙個控制代碼來儲存載入dll的返回值,還要定義帶引數的指標型別儲存獲得的兩個函式位址typedef int (*pfunc)(int,int);,在對話方塊標頭檔案的類中如下:
public:
hmodule hdlllib;
pfunc m_psum;
pfunc m_psub;
在對話方塊的初始化中新增dll載入過程:
hdlllib = loadlibrary("mfcdll.dll");
if(hdlllib == null)
m_psum = (pfunc)getprocaddress(hdlllib,"sum"); //強制型別轉換一定要加,getprocaddress預設返回不帶引數的函式指標
m_psub = (pfunc)getprocaddress(hdlllib,"sub");
為了完整性,在對話方塊的wm_destory訊息的響應函式ondestroy()中新增:
freelibrary(hdlllib);
這樣,兩個按鈕的操作如下:
void cmfcdlltest2dlg::onsum()
void cmfcdlltest2dlg::onsub()
動態載入不需要lib檔案,只要把dll檔案放在exe同目錄下即可執行。
(3)win32 dll說明
win32 dll與mfc dll的差別在於它的dllmain不是打包的,是可見的。它同樣其中定義函式實體,不過在標頭檔案中都需要申明(申明語句是特定的,如extern "c" __declspec( dllexport ) )。預設的入口函式如下:
bool apientry dllmain( handle hmodule,
dword ul_reason_for_call,
lpvoid lpreserved
)return true;
}dllmain負責初始化和結束工作。
hmodule是動態庫被呼叫時所傳遞過來的乙個指向自己的控制代碼;
ul_reason_for_call是乙個說明動態庫被呼叫原因的標誌。當程序或者執行緒裝載、解除安裝動態鏈結庫的時候,作業系統便呼叫入口函式。dll_process_attach:當乙個dll被首次載入程序位址空間時,系統會呼叫該dll的dllmain函式,傳遞的引數fdwreason為dll_process_attach。這種情況只有在首次對映dll時才發生。
dll_process_detach:當dll從程序的位址空間解除對映時,引數fdwreason被傳遞的值為dll_process_detach。當dll處理dll_process_detach時,dll應該處理與程序相關的清理操作。
lpreserved是乙個被系統保留的引數
理解以上之後,就需要考慮輸出函式的實現方法。
(4)建立win32 dll
a,用vc6建立乙個win32 dll工程win32dll,可以看出它預設用win32dll_api這個符號輸出乙個變數nwin32dll 和乙個函式fnwin32dll,而win32dll_api相當於__declspec(dllexport)。類似,在對話方塊標頭檔案中新增輸出申明,同時需要特別關注的是在申明和定義前都要加extern "c"關鍵字,如果不加在隱式呼叫和顯式呼叫時會出現異常狀況:
extern "c" win32dll_api int sum(int a,int b);
extern "c" win32dll_api int sub(int a,int b);
在對話方塊c檔案完成函式體:
extern "c" win32dll_api int sum(int a,int b)
extern "c" win32dll_api int sub(int a,int b)
編譯就生成對應的lib和dll。
b,隱式載入win32 dll並測試
利用第(2)步同樣的隱式呼叫測試程式,就可以測試這個dll。有點差別,就是標頭檔案前也要加extern "c",否則編譯錯誤。如下:
#pragma comment(lib,"win32")
extern "c" int sum(int a,int b);
extern "c" int sub(int a,int b);
過程是講lib拷貝至測試程式工程目錄下,將dll拷貝至exe同層目錄下。
c,顯式載入win32 dll並測試
利用第(2)步同樣的顯式呼叫程式即可。如果win32 dll中沒有加extern "c" 關鍵字,則取函式位址時異常。
MFC動態鏈結庫和WIN32動態鏈結庫 及區別
1 dll的構成 每個應用程式都有乙個入口函式winmain,而每個dll也有乙個入口函式dllmain。dll跟應用程式一樣都含有資源 資料段和 段。dll跟應用程式的差別主要是dll有符號輸入表和符號輸出表,以方便應用程式呼叫dll中的函式。因為dll是由應用程式載入的,所以它本身沒有虛擬的記憶...
Win32 動態鏈結庫 二
1.檔案 新建 空專案 include windows.h include stdio.h pragma comment lib,debug xxp dll test.lib extern c declspec dllimport int addfun int a,int b 匯入動態鏈結庫的add...
Win32下動態鏈結庫 DLL 程式設計
主題 dll是windows最重要的組成要素,windows中的許多新功能 新特性都是通過dll來 實現的,因此掌握它 應用它是非常重要的。動態鏈結庫不僅可以作為乙個執行模組,包括函式 而且可以包含程式以外的任何資料 或資源 位圖 圖示等等 動態鏈結庫就是給應用程式提供函式或者資源。dll是一種磁碟...