Windows API 教程(六) 動(dòng)態(tài)鏈接庫(kù) 簡(jiǎn)介 動(dòng)態(tài)鏈接庫(kù)(DLL,全稱Dynamic Link Library)進(jìn)程之間共享使用的函數(shù)庫(kù),。動(dòng)態(tài)鏈接庫(kù)提供了一種方法,,是進(jìn)程可以調(diào)用不屬于其自身可執(zhí)行代碼的函數(shù)。函數(shù)的可執(zhí)行代碼位于一個(gè)DLL中,,當(dāng)調(diào)用DLL中的方法時(shí),,進(jìn)程由原本自身的代碼執(zhí)行到DLL中。DLL有助于程序模塊化,,減少重復(fù)開(kāi)發(fā),。 在這之前已經(jīng)提到的多次的 kernel32.dll ,也即 windows 的核心DLL,,我們進(jìn)行 windows 編程開(kāi)發(fā)中很多函數(shù)都是從其中導(dǎo)出,。 編寫 DLL1) 新建項(xiàng)目 【文件】->【新建】->【項(xiàng)目】->選擇【win32 項(xiàng)目】->【下一步】->【DLL 空項(xiàng)目】 新建項(xiàng)目的目錄要記一下,等會(huì)會(huì)用到,。 2)開(kāi)始編寫 DLL dll.h1 2 3 4 5 6 7 8 | #ifdef MYDLL_EXPORTS
#define MYDLL_API _declspec(dllexport)
#else
#define MYDLL_API _declspec(dllimport)
#endif
// 聲明自定義導(dǎo)出函數(shù)
MYDLL_API void helloDLL( void );
|
dll.c1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <windows.h>// for MessageBox
#include "dll.h" // 引用導(dǎo)出定義
// DLL入口函數(shù)
BOOL APIENTRY DllMain( HANDLE hModule, DWORD dwReason, void * lpReserved)
{
switch (dwReason)
{
// 動(dòng)態(tài)鏈接庫(kù)映射到某個(gè)進(jìn)程的地址空間
case DLL_PROCESS_ATTACH:
/**
* 當(dāng)DLL剛被加載時(shí)觸發(fā)(LoadLibrary),,此處專門用來(lái)做初始化工作,
* 如果初始化失敗可以返回 false 這樣DLL就不會(huì)被繼續(xù)加載了
**/
break ;
// 應(yīng)用程序創(chuàng)建新的線程
case DLL_THREAD_ATTACH:
break ;
// 應(yīng)用程序某個(gè)線程正常終止
case DLL_THREAD_DETACH:
break ;
// 動(dòng)態(tài)鏈接庫(kù)將被卸載
case DLL_PROCESS_DETACH:
/**
* 當(dāng)DLL將要被卸載時(shí)觸發(fā)(FreeLibrary),此處專門用來(lái)做清理工作
* 如關(guān)閉文件,,釋放內(nèi)存空間等
**/
break ;
}
return 1;
}
void helloDLL( void )
{
MessageBox(NULL, TEXT( "Hello DLL~" ), TEXT( "Title" ), MB_OK);
}
|
編寫好之后 F7 生成(visual studio 2008以上),,到項(xiàng)目的 Debug 目錄下找到生成的 DLL 一般是 【項(xiàng)目名.DLL】 調(diào)用 DLL再新建一個(gè)普通的【空項(xiàng)目】就可以了 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <stdio.h>
#include <windows.h>
// 指向函數(shù)的指針類型
typedef void (*fun_pointer)( void );
// main
VOID main( VOID )
{
HINSTANCE hDLL;
BOOL flagGetFun = FALSE;
fun_pointer p;
// 加載 Dll
hDLL = LoadLibrary(TEXT( "DLLTEST.dll" ));
// 判斷是否加載成功
if (hDLL != NULL)
{
printf ( "模塊加載成功\n" );
// 獲得指定導(dǎo)出函數(shù)的地址
p = (fun_pointer) GetProcAddress(hDLL, "helloDLL" );
// 判斷是否成功
if (NULL != p)
{
printf ( "函數(shù)獲取成功,準(zhǔn)備調(diào)用函數(shù)\n" );
p(); // 成功則調(diào)用DLL中的函數(shù)
} else
{
printf ( "函數(shù)獲取失??!\n" );
printf ( "error: %u\n" , GetLastError());
}
// 釋放DLL
if (!FreeLibrary(hDLL))
{
printf ( "DLL釋放失敗\n" );
printf ( "error: %u\n" , GetLastError());
}
} else
{
printf ( "模塊加載失敗,!\n" );
printf ( "error: %u\n" , GetLastError());
}
system ( "pause" );
}
|
編寫好之后,,點(diǎn)擊生成,將開(kāi)始的 DLL 文件拷貝到該項(xiàng)目的 Debug 目錄(與exe同一個(gè)目錄),,接著雙擊執(zhí)行即可,。
源碼下載
|