این فایل ها همانند ساختار فایل های exe در ویندوز دارای ساختار (pe (Portable Executable میباشد .
این کتابخانه ها میتوانن شامل کد و دیتا و ریسورسها باشند .
یکی از مزایای فایل های dll این است که یک بار در حافظه لود میشود و میتواند توسط چندین برنامه مورد استفاده قرار گیرد(به صورت مجازی برای هر برنامه کپی میشود ) . میتوان dll ها را در موقه نیاز در برنامه لود کرد و هر جا که دیگر مورد نیاز نبود آن را Unload کرد .
از طرفی دیگر میتوان از آن برای استفاده از برنامه های قابل آبدیت نیز استفاده کرد به این صورت که میتوان آیکن ها ، فونت ها و کد هایی که در هسته اصلی برنامه جایگاهی ندارند را درون dll ها قرار داد و در هنگام آبدیت تنها این dll ها را تعویض کرد.
هر فایل اجرایی بغیر از کد ها و داده های خود میتواند اطلاعات را از خارج از خود و از dll بگیرد . در هر فایل pe بخشی از هدر فایل ، شامل آدرس جدول آدرس ایمپورت ها میشود که اطلاعات موجود در آن ، آدرس توابعی که از dll ها فراخوانی میشود را در خود نگه داری میکنند( البته این آدرس ها با بیس آدرس dll ترکیب میشوند که در تصویر دوم هم قابل مشاهده است ).
عکس زیر خلاصه ای ار هدر فایلهایی با ساختار PE میباشد . در این عکس import adress table حاوی آدرس iat در برنامه میباشد .
شکل زیر یک توضیح کلی تر و بهتر در اختیار ما میگذارد . در این شکل میتوان iat را بین دو سکشن کد و دیتا ببینید ( لزوما جای iat اینجا نمیباشد ) .
نمونه ای از فراخوانی یکی از 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
شکل کلی استفاده از این دستور :
با اجرای این دستور پنجره ای را میبینید که در آن پیغام موجود در dll را چاپ میکند .
RUNDLL32.EXE <dllname>,<entrypoint> <optional arguments>
مثال دوم :
در این مثال ، دی ال الی که در مثال قبل ساختیم را در یک برنامه دیگر با زبان 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;
}