در خلاصه ترین حالت میتوان گفت Dynamic link library نام کتابخانه هایی است که توسط برنامه ها استفاده میشوند و توسط مایکروسافت پیاده سازی شده ( که اغلب دارای پسوند dll میباشند ) .
این فایل ها همانند ساختار فایل های exe در ویندوز دارای ساختار (pe (Portable Executable میباشد .
این کتابخانه ها میتوانن شامل کد و دیتا و ریسورسها باشند .
یکی از مزایای فایل های dll این است که یک بار در حافظه لود میشود و میتواند توسط چندین برنامه مورد استفاده قرار گیرد(به صورت مجازی برای هر برنامه کپی میشود ) . میتوان dll ها را در موقه نیاز در برنامه لود کرد و هر جا که دیگر مورد نیاز نبود آن را Unload کرد .
از طرفی دیگر میتوان از آن برای استفاده از برنامه های قابل آبدیت نیز استفاده کرد به این صورت که میتوان آیکن ها ، فونت ها و کد هایی که در هسته اصلی برنامه جایگاهی ندارند را درون dll ها قرار داد و در هنگام آبدیت تنها این dll ها را تعویض کرد.


Dynamic link library


هر فایل اجرایی بغیر از کد ها و داده های خود میتواند اطلاعات را از خارج از خود و از dll بگیرد . در هر فایل pe بخشی از هدر فایل ، شامل آدرس جدول آدرس ایمپورت ها میشود که اطلاعات موجود در آن ، آدرس توابعی که از dll ها فراخوانی میشود را در خود نگه داری میکنند( البته این آدرس ها با بیس آدرس dll ترکیب میشوند که در تصویر دوم هم قابل مشاهده است ).

عکس زیر خلاصه ای ار هدر فایلهایی با ساختار PE میباشد . در این عکس import adress table حاوی آدرس iat در برنامه میباشد .

Portable_Executable_32_bit

شکل زیر یک توضیح کلی تر و بهتر در اختیار ما میگذارد . در این شکل میتوان iat را بین دو سکشن کد و دیتا ببینید ( لزوما جای iat اینجا نمیباشد ) .

pe

نمونه ای از فراخوانی یکی از dll ها رو کد زیر میتوان مشاهده کرد . این تصویر دیس اسمبل شده یک برنامه میباشد .

call_dll

مثال های کاربردی :

مثال اول:
در مثال اول یک dll ساخته و آن را با rundll32.exe اجرا میکنیم .
از قسمت نیو پراجکت در قسمت سی پلاس پلاس پروژه ای از نوع win32project میسازیم . در صفحه باز شده نکست را میزنیم . dll را انتخاب کرده و سپس تیک فینیش را میزنیم .
سپس به پروژه خود یک فایل cpp اضافه میکنیم و کد های زیر را در آن مینویسیم :

//[dll01.dll]
#include <windows.h>

extern "C" __declspec (dllexport) void
__cdecl hello()
{
::MessageBox(0, L"hello world", 0, 0);
}

BOOL APIENTRY Dll(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
return TRUE;
}
برنامه را کامپایل میکنیم .
سپس cmd را باز کرده و دستور زیر را در آن مینویسیم .
(در آدرسی که dll قرار دارد دستور را اجرا کنید یا این که آدرس کامل dll را به آن بدهید)
c:\rundll32.exe dll01.dll,hello
شکل کلی استفاده از این دستور :
RUNDLL32.EXE <dllname>,<entrypoint> <optional arguments>
با اجرای این دستور پنجره ای را میبینید که در آن پیغام موجود در dll را چاپ میکند .

مثال دوم :
در این مثال ، دی ال الی که در مثال قبل ساختیم را در یک برنامه دیگر با زبان c++ لود و بعد از اتمام کار، آن را آن لود میکنیم .
سورس برنامه مورد نظر :

#include <windows.h> 
#include <stdio.h>

typedef void(__cdecl *MYPROC)();

int main(void)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;

// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("c://dll01.dll"));

// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "hello");

// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
printf("dll is loaded\n");
fRunTimeLinkSuccess = TRUE;
(ProcAdd)();
}

// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);

if (fFreeResult && ProcAdd)
{
printf("dll is Unloaded\n");
}
else if (!fFreeResult && ProcAdd)
{
printf("error , dll is not Unload\n");
}
}

// If unable to call the DLL function, use an alternative.
if (!fRunTimeLinkSuccess)
{
printf("Message printed from executable\n");
}

system("pause");
return 0;
}