動(dòng)態(tài)連接庫
1.動(dòng)態(tài)連接庫是一些獨立的文件,其中包含能被可執行程序或其它DLL調用來(lái)完成某項工作的函數。只有在其它模塊調用動(dòng)態(tài)連接庫中的函數時(shí),它才發(fā)揮作用。
2.Windows API 中的所有函數都包含在DLL中。 Kernel32.dll,它包含用于管理內存、進(jìn)程和線(xiàn)程的各個(gè)函數;User32.dll,包含用于執行用戶(hù)界面任務(wù)(如窗口的創(chuàng )建和消息的傳送)的各個(gè)函數;GDI32.dll,它包含用于畫(huà)圖和顯示文本的各個(gè)函數。
靜態(tài)庫和動(dòng)態(tài)庫
1.靜態(tài)庫:函數和數據被編譯進(jìn)一個(gè)二進(jìn)制文件(通常為 .LIB )。 編譯連接 .exe 文件時(shí),連接器從庫中復制這些函數和數據并把它們和應用程序的其他模塊組合起來(lái)創(chuàng )建最終的 .exe 文件。
發(fā)布時(shí)只需發(fā)布 .exe 文件而無(wú)需提供靜態(tài)庫文件。
2.在使用動(dòng)態(tài)庫的時(shí)候,往往提供兩個(gè)文件:一個(gè) 引入庫( .lib ) 和一個(gè) DLL。引入庫包含被DLL導出的 函數和變量的符號名,DLL包含實(shí)際地函數和數據。編譯連接 .exe 時(shí),只需要鏈接引入庫,運行時(shí)再去加載DLL,訪(fǎng)問(wèn)DLL中導出的函數。發(fā)布時(shí)需要發(fā)布DLL。
使用動(dòng)態(tài)連接庫的好處
1.可以采用多種語(yǔ)言來(lái)編寫(xiě)。( 在VB中調用用VC寫(xiě)的封裝了業(yè)務(wù)邏輯的DLL )。
2.增強產(chǎn)品的功能。
發(fā)布產(chǎn)品的同時(shí)發(fā)布 dll規范,其他人可以按規范編寫(xiě)dll替換只,以達到功能的增強。例如:skin,替換UI的動(dòng)態(tài)連接庫。
3.提供二次開(kāi)發(fā)的平臺。
4.簡(jiǎn)化項目管理。
5.節省磁盤(pán)空間和內存。
如果 .dll 已加載到內存,如果其他程序也需要該模塊,則不需要再加載到內存中, x86的頁(yè)面大小是4KB。
6.有助于資源的共享。 可以編寫(xiě)純資源的動(dòng)態(tài)連接庫,供其他app訪(fǎng)問(wèn)。
7.用助于實(shí)現應用程序的本地化。 為每種語(yǔ)言提供只支持這種語(yǔ)言的動(dòng)態(tài)連接庫。
動(dòng)態(tài)連接庫被多個(gè)進(jìn)程訪(fǎng)問(wèn)
將.DLL 的虛擬內存中的代碼頁(yè)面和數據頁(yè)面映射到不同進(jìn)程的地址空間中去。
動(dòng)態(tài)連接庫加載的兩種方式
1.隱式鏈接
ProjectSetting -> Link -> Object/Libary Modules: => dll1.lib(為運行時(shí)加載dll提供重定位表)
#include ".\dll1.h"
dll1.cpp
#define DLL1_API extern "C"_declspec(dllexport)
#include "dll1.h" //頭文件不參與編譯,源文件單獨編譯
#include <windows.h>
#include <stdio.h>
int _stdcall add( int a, int b ) { return a + b; }
int _stdcall subtract( int a, int b ) { return a - b; }
/* void MyPoint::output( int x, int y )
{ HWND hwnd = GetForegroundWindow();
HDC hdc = GetDC( hwnd );
char buf[20]; memset( buf,0,20);
sprintf( buf, "x=%d, y=%d", x, y );
TextOut( hdc, 0, 0, buf, strlen( buf ) );
ReleaseDC( hwnd,hdc ); } */
Depends.exeexe
2.顯式加載
名字改編:通過(guò)模塊定義文件解決
EXPORTS
entryname[=internalname] [@ordinal [NONAME]] [PRIVATE] [DATA]
HMODULE LoadLibrary(LPCTSTR lpFileName );FARPROC GetProcAddress( HMODULE hModule, LPCSTR lpProcName );
dll2.cpp
int _stdcall add( int a, int b ) { return a + b; }
int _stdcall subtract( int a, int b ) { return a - b; }
dll2.def
LIBRARY dll2
EXPORTS
add
subtract
HINSTANCE hInst;
hInst = LoadLibrary( "dll2.dll" ); //
if( NULL == hInst ) { AfxMessageBox("dll2.dll未成功加載!" ); return; } //
typedef int( _stdcall *ADDPROC )( int a, int b );
ADDPROC ADD = (ADDPROC)GetProcAddress( hInst, "add" ); //
if( !ADD ) { AfxMessageBox( "獲取函數地址失??!" ); return; }
CString str;
str.Format( "5 + 3 = %d", ADD( 5, 3 ) );
AfxMessageBox( str );
Note:注意調用約定
DLLMain
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved );
fdwReason:
DLL_PROCESS_ATTACH 1
DLL_THREAD_ATTACH 2
DLL_THREAD_DETACH 3
DLL_PROCESS_DETACH 0
MFC擴展DLL
減少對該module的引用計數
BOOL FreeLibrary( HMODULE hModule );
dll1.h(供客戶(hù)使用)
聯(lián)系客服