کتابخانه پیوند پویا

**کتابخانه پیوند پویا** (یا **DLL**)یک فرمت استاندارد پیاده‌سازی شده توسط مایکروسافت از مفهوم کتابخانه‌های مشترک در سیستم عامل‌های مایکروسافت ویندوز و OS / 2 است. این کتابخانه‌ها معمولاً دارای فایل‌های `DLL`، `OCX` (برای کتابخانه‌های حاوی کنترل‌های اکتیو ایکس) یا `DRV` (برای رانندگان سیستم میراث) هستند. فرمت‌های فایل DLLها همانند فایل‌های ویندوز EXE است - یعنی قابل اجرا و قابل حمل (یا PE) برای ویندوزهای ۳۲ بیتی و ۶۴ بیتی و NE)New Executable) برای ویندوزهای ۱۶ بیتی. همانند EXEها، DLLها می‌توانند شامل کد، داده‌ها و منابع در هر ترکیبی از آن‌ها باشند.
فایلهای داده با فرمت فایل DLL، اما با پسوندهای فایلی مختلف که احتمالاً هم فقط شامل بخش منابع باشند، می‌توانند *منابع DLL* نامیده شوند. نمونه‌هایی از چنین DLL شامل *[[نقشک|آیکون]] کتابخانه هاست که* گاهی اوقات دارای پسوند`ICL`و فایل‌های فونت، که دارای پسوندهای `FON` و `FOT` هستند، می‌شود.

به عبارت دیگر برنامه نویسان می‌توانند توابعی مورد نیاز خود که در فایل‌های DLL قرار دارند را به برنامه خود لینک کنند و از آن استفاده کنند.

از این فایل‌ها می‌توان در چندین برنامه به صورت همزمان هم استفاده کرد و در نتیجه این کار باعث افزایش کارایی برنامه نویسان و استاندارد درسیستم عامل می‌شود.

## پس زمینهٔ DLL
اولین نسخه‌های مایکروسافت ویندوز، برنامه هارا در یک فضای آدرس واحد، باهم اجرا می‌کرد. هر برنامه برای این درست شده بود تا به این صورت همکاری کند که CPU را به برنامه‌های دیگر هم برساند (yield کند)، تا رابط کاربری گرافیکی (GUI) بتواند چند کا را با هم انجام دهد و حداکثر پاسخگویی را داشته باشد. تمام عملیات سیستم عامل توسط سیستم عامل پایه ارائه شده‌است: MS-DOS. تمام خدمات سطح بالا توسط کتابخانه‌های ویندوز، همان "DLL"ها، ارائه شده‌است. API طراحی، رابط گرافیکی دستگاه (GDI)، در یک DLL با نام `GDI.` `EXE` پیاده‌سازی شده‌است، رابط کاربر در `USER.` `EXE` . این لایه‌های اضافی در بالای DOS باید در همه برنامه‌های در حال اجرای ویندوز به اشتراک گذاشته می‌شد، نه فقط برای فعال کردن ویندوز برای کار در یک ماشین با کمتر از یک مگابایت RAM، بلکه برای فعال کردن برنامه‌ها برای همکاری با یکدیگر. کد در GDI نیاز داشت تا دستورات رسم را به یکسری عملیات در دستگاه‌های خاص ترجمه کند. در صفحه نمایش، باید پیکسل‌ها را در بافر فریم مورد استفاده قرار می‌داد. هنگام طراحی به یک چاپگر، درخواست API باید به درخواست‌هایی به یک چاپگر تبدیل می‌شد. اگر چه می‌توانست امکان‌پذیر باشد که پشتیبانی سخت‌افزاری برای مجموعه محدودی از دستگاه‌ها (مانند صفحه نمایش رنگی گرافیک آداپتور، پرینتر لیزریجت چاپگر فرمان زبان) فراهم شود، مایکروسافت رویکردی متفاوت انتخاب کرد. GDI با بارگیری قطعات مختلفی از کد، به نام " درایور دستگاه "، برای کار با دستگاه‌های خروجی مختلف کار می‌کرد.

همان مفهوم معماری که GDI را قادر ساخت تا دستگاهای درایور مختلف بار شوند، همان است که به ویندوز شل (windows shell) اجازه داد تا برنامه‌های مختلف ویندوز را بارگذاری کند و برای این برنامه‌ها که بتوانند APIها را از کتابخانه‌های مشترک USER و GDI فراخوانی کنند. آن مفهوم «پیوند پویا» نام داشت.

در یک کتابخانه «استاتیک» معمولی (که مشترک(shared) نباشد)، به سادگی بخش‌های کد به برنامهٔ فراخوانی شده اضافه می‌شوند، زمانی که فایل اجرایی آن در مرحله «اتصال» ساخته شده‌است؛ اگر دو برنامه با یک تابع را صدا بزنند، آن تابع در هر دو برنامه، در مرحله اتصال هر دو، گنجانده می‌شود. با پیوند پویا، کد مشترک، در یک فایل جداگانه قرار می‌گیرد. برنامه‌هایی که این پرونده را فراخوانی می‌کنند در زمان اجرا، با سیستم عامل (یا، در مورد نسخه‌های اولیه ویندوز، OS-extension)، با اتصال به آن، مرتبط می‌شوند.

برای نسخه‌های اولیه ویندوز (۱٫۰ تا ۳٫۱۱)، DLLها پایه و اساس کل رابط‌های کاربری گرافیکی (GUI) بودند. به همین ترتیب، درایورهای نمایش صرفاً فقط DLLهایی با پسوند DRV بودند که برنامه‌های پیاده‌سازی شدهٔ سفارشی از همان طراحی API را از طریق یک دستگاه درایور متحد رابط (DDI) فراهم می‌کرد و "رسم (GDI)" و " USER) GUI)" همان APIها صرفاً یکسری فراخوانی تابع بودند که توسط GDI و USER و سیستم DLLها با پسوند .EXE صادر شدند.

مفهوم ساخت سیستم عامل از مجموعه ای از کتابخانه‌های بارگذاری شده به صورت پویا، یک مفهوم اصلی ویندوز است که  ادامه می‌یابد. DLLها مزایای استاندارد کتابخانه‌های به اشتراک گذاشته شده، مانند ماژولار بودن را فراهم می‌کنند. ماژولار بودن اجازه می‌دهد تا تغییرات در کد و داده‌ها در یک DLL خود درج و پر شده‌ای که توسط تعدادی نرم‌افزار مختلف بدون ایجاد هیچ تغییری در خود نرم‌افزارها به اشتراک گذاشته شده‌است، صورت گیرد.

یکی دیگر از مزایای ماژولار بودن استفاده از رابط‌های عمومی برای پلاگ-این‌ها است. یک رابط واحد ممکن است توسعه یابد، که اجازه می‌دهد که ماژول‌های قدیمی و جدید به‌طور یکپارچه با هم در زمان اجرا متحد شوند و تبدیل شوند به برنامه‌های از قبل وجود داشته، بدون هیچ گونه تغییری در خود نرم‌افزار. این مفهوم توسعه پویا به بیشترین حد خود، با مدل Object Component، پایهٔ ActiveX، رسیده‌است.

در ویندوز x.1، 2.x و 3.x، تمام نرم‌افزارهای ویندوز یک فضای آدرس حافظه را به اشتراک می‌گذاشتند. یک DLL فقط یک بار به این فضای آدرس بارگذاری شد. از آن پس، تمام برنامه‌هایی که از کتابخانه استفاده می‌کردند می‌توانستند به آن دسترسی پیدا کنند. داده‌های کتابخانه در همه برنامه‌ها به اشتراک گذاشته شده‌است. این می‌تواند به عنوان یک شکل غیرمستقیم ارتباطات بین فرایند مورد استفاده قرار گیرد، یا می‌تواند به‌طور تصادفی برنامه‌های مختلف را فاسد کند. با معرفی کتابخانه‌های ۳۲ بیتی در ویندوز ۹۵، هر فرایند در فضای آدرس خود اجرا می‌شود. در حالی که کد DLL ممکن است به اشتراک گذاشته شود، داده‌ها خصوصی هستند مگر اینکه داده‌های به اشتراک گذاشته شده، به‌طور صریح از سوی کتابخانه درخواست شوند. با توجه به این موضوع، نوارهای بزرگی از کتابخانه‌های ۱۶ بیتی از ویندوز ۹۵، ویندوز ۹۸ و ویندوز می ساخته شد که عملکرد ریز پردازنده‌های **[[پنتیوم پرو]]** را در هنگام شروع محدود کرد و در نهایت ثبات و مقیاس پذیری نسخه‌های مبتنی بر DOS را محدود کرد.

اگر چه DLLها هسته معماری ویندوز هستند، اما آن‌ها دارای نقایص متعددی هستند که به‌طور کلی " **[[جهنم دی‌ال‌ال]]** " نامیده می‌شود. ، مایکروسافت NET چارچوب را رواج می‌دهد، به عنوان یک راه حل برای مشکلات DLL hell، اگر چه آن‌ها در حال حاضر راه حل‌های مبتنی بر مجازی سازی را مانند مایکروسافت مجازی کامپیوتر و مایکروسافت برنامه مجازی سازی رواج می‌دهند و آن به دلیل انعطاف‌پذیری بالاتر بین برنامه‌های کاربردی است. راه حل جبران جایگزین برای DLL hell، اجرای اسمبلی کنار هم قرار گرفته‌است.

## ویژگی‌های DLL
از آنجائیکه DLLها اساساً همان EXEها هستند، انتخاب آن برای تولید به عنوان بخشی از روند پیوند برای وضوح است، به این دلیل که ممکن است توابع و داده‌ها را از هر دوی آن‌ها بفرستد.

امکان اجرای مستقیم DLL وجود ندارد، زیرا برای سیستم عامل نیاز به یک EXE است، تا بتواند آن را از هر نقطه ورود بارگذاری کند. از این رو، وجود امکانات مانند "RUNDLL. EXE" یا "RUNDLL32.EXE" که نقطه ورود و حداقل چارچوب را برای DLLها فراهم می‌کند که دارای قابلیت کافی برای اجرا بدون پشتیبانی زیاد است.

DLLها مکانیسم لازم برای کد و داده مشترک را فراهم می‌کنند و با اینکار اجازه می‌دهند یک توسعه دهندهٔ کد/دادهٔ مشترک، بدون اینکه نیاز داشته باشد تا برنامه‌ها پیوند دوباره بخورند یا مجدداً کامپایل شوند، عملکرد خود را ارتقا دهد. از نقطه نظر توسعه نرم‌افزار، ویندوز و OS / 2 می‌توانند به عنوان مجموعه ای از DLLهایی که به روز رسانی شده‌اند، باشند که اجازه می‌دهد برنامه‌های کاربردی برای یک نسخه از سیستم عامل بدر یک نسخه دیگر آن نیز کار کند. در صورتی که فروشنده OS مطمئن شده‌است که رابط و قابلیت هر دو سازگار هستند.

DLLها در فضای حافظه در فرایند فراخوانی اجرا می‌شوند و با مجوزهای دسترسی برابر، که بدین معناست که در استفاده، آن‌ها کم هزینه هستند، اما همچنین به این معناست که اگر DLL هر گونه مشکلی داشته باشد، هیچ حفاظتی در فراخوانی EXE وجود ندارد.

### مدیریت حافظه
در ویندوز API، فایل‌های DLL به *[[قطعه‌بندی|بخش]]*هایی سازماندهی شده‌اند. هر بخش مجموعه ای از ویژگی‌های خاص خود را دارد، از قبیل قابل خواندن و نوشتن، اجرایی بودن (برای کد) یا غیرقابل اجرایی بودن (برای داده‌ها) و غیره.

کد در DLL معمولاً در میان تمام فرایندهای که از DLL استفاده می‌کنند به اشتراک گذاشته می‌شود؛ یعنی، آن‌ها یک مکان را در حافظه فیزیکی اشغال می‌کنند و در فضای صفحه فضایی نمی‌گیرند. اگر حافظه فیزیکی اشغال شده توسط یک بخش کد بخواهد بازسازی شود، محتویات آن حذف می‌شود و بعد از آن به‌طور مستقیم از فایل DLL به صورت مجدد بارگیری می‌شود.

برخلاف بخش‌های کد، بخش داده‌های یک DLL معمولاً خصوصی هستند؛ یعنی هر فرایندی که از DLL استفاده می‌کند، یک کپی مخصوص از تمام داده‌های DLL دارد. به صورت اختیاری، بخش‌های داده می‌توانند به اشتراک گذاشته شوند، به این ترتیب می‌توان اجازه داد ارتباطات فرایند از طریق این فضای حافظهٔ به اشتراک گذاشته شده، صورت گیرند. به هر جهت، به دلیل اینکه محدودیت‌های کاربر برای استفاده از حافظه DLL مشترک اعمال نمی‌شود، این یک سوراخ امنیتی ایجاد می‌کند؛ یعنی یک فرایند می‌تواند داده‌های مشترک را خراب کند، که احتمالاً باعث می‌شود همه فرایندهای به اشتراک گذاری غیرمعمول رفتار کنند. به عنوان مثال، فرایندی که تحت یک حساب مهمان انجام می‌شود، می‌تواند به این ترتیب فرایند دیگری را که تحت یک حساب کاربری مجاز است خراب کند. این یک دلیل مهم برای جلوگیری از استفاده از بخش‌های مشترک در DLLها است.

اگر یک DLL با برخی بسته‌بندی‌های اجرایی خاص فشرده شود (به عنوان مثال UPX)، تمام بخش‌های کد آن به عنوان خواندن و نوشتن مشخص شده‌اند و به اشتراک گذاشته نمی‌شوند. بخش‌های خواندن و نوشتن کد، شبیه به بخش‌های داده‌های خصوصی، برای هر فرایند خصوصی هستند؛ بنابراین، DLLها با بخش‌های داده مشترک، اگر آن‌ها برای این در نظر گرفته شده باشند که به‌طور همزمان توسط چندین برنامه استفاده شوند، نباید فشرده شوند؛ چرا که هر نمونه از برنامه باید یک کپی خود از DLL را حمل کند که در نتیجه افزایش مصرف حافظه خواهد بود.

### فراخوانی کتابخانه‌ها
همانند کتابخانه‌های استاتیک، کتابخانه‌های دخیل شده برای DLLها با فرمت فایل lib مشخص می‌شوند. به عنوان مثال، kernel32.dll، کتابخانه پویا اولیه برای توابع پایه ویندوز مانند ایجاد فایل و مدیریت حافظه، از طریق kernel32.lib مرتبط شده.

پیوستن به کتابخانه‌های پویا معمولاً با اتصال به یک کتابخانه وارد شده و دخیل شده به آن رسیدگی می‌شود؛ هنگام ساختن یا متصل شدن برای ایجاد یک فایل اجرایی. سپس فایل اجرایی ساخته شده، حاوی یک جدول آدرس‌های دخیل (IAT) است که توسط آن تمام فراخوانی‌های عملکرد DLL ارجاع می‌شود. (هر تابع اشاره شده DLL دارای ورودی خود در IAT است). در زمان اجرا، IAT با آدرس‌های مناسب پر می‌شود که مستقیماً به یک تابع در DLL ای که جداگانه بارگذاری شده، اشاره می‌کند.

### رفع نماد و الزام آن
هر تابعی که توسط یک DLL صادر می‌شود، توسط یک عدد ترتیبی و به صورت اختیاری، با یک نام شناسایی می‌شود. به همین ترتیب، توابع را می‌توان از یک DLL یا به ترتیب یا با نام وارد کرد. ترتیب آن نشان دهنده موقعیت نشانگر آدرس تابع در جدول آدرس‌های دخیل DLL یا همان IAT است. معمول است که توابع داخلی فقط به ترتیب صادر شوند نه با نام. برای اکثر توابع API ویندوزها، فقط نام‌ها در نسخه‌های مختلف ویندوز حفظ می‌شوند؛ آن اعداد ترتیبی در معرض تغییر هستند؛ بنابراین، یکنفر نمی‌تواند با اعتماد کامل توابع API ویندوز را با اعدادش وارد کند.

فراخوانی توابع با اعدادشان، تنها عملکرد آن را به مقدار خیلی کمی بهتر می‌کند در مقایسه با فراخوانی آن‌ها با نامشان: جداول صادر کردن DLLها با نامشان ترتیب بندی شده‌اند؛ بنابراین از جستجو باینری می‌توان برای پیدا کردن یک تابع استفاده کرد. سپس فهرست نام پیدا شده در این جستجو، مورد استفاده قرار می‌گیرد تا عدد آن را در جدول اعداد صادره رپیدا کند. در ویندوز ۱۶ بیتی، جدول نام طبقه‌بندی نشده بود، بنابراین هزینهٔ جستجوی نام بسیار قابل توجه بود.

همچنین ممکن است که یک فایل اجرایی را به یک نسخه خاص از یک DLL *متصل کنیم*، این کار برای این است که آدرس‌های توابع فراخوانی شده در زمان کامپایل حل و فصل شوند. برای توابع فراخوانی شدهٔ محدود، لینکر نشانهٔ زمانی و مجموع مقابله‌های DLL که فراخوانی در آن محدود است را ذخیره می‌کند. در زمان اجرا، ویندوز بررسی می‌کند که آیا همان نسخه از کتابخانه در حال استفاده است یا خیر، اگر اینطور بود، ویندوز از پردازش توابع فراخوانی شده جلوگیری می‌کند. در غیر این صورت، اگر کتابخانه با آن کتابخانه ای که به آن محدود شده بود متفاوت بود، ویندوز به‌طور عادی فراخوانده شده‌ها را پردازش می‌کند.

فایل‌های اجرایی محدود شده به نحوی سریعتر بارگذاری می‌شوند اگر که در همان محیطی که برای کامپایل شدن آن‌ها بوده، اجرا شوند و دقیقاً در همان زمان اگر در محیطهای متفاوتی اجرا می‌شوند؛ بنابراین هیچ محدودیتی برای اتصال به فراخوانی شده‌ها وجود ندارد. به عنوان مثال، تمام برنامه‌های ویندوز استاندارد به DLLهای سیستم مربوط به آن نسخه از ویندوز محدود می‌شوند. یک فرصت خوب برای اتصال توابع فراخوانده شدهٔ یک نرم‌افزار به محیط هدف خود، در طول نصب نرم‌افزار است. این کار کتابخانه‌ها را تا ارسال نسخهٔ بعدی سیستم عامل محدود می‌کند؛ ولی مجموع مقابله‌های برنامهٔ اجرایی را تغییر می‌دهد؛ بنابراین چیزی نیست که بتوان با برنامه‌های امضا شده یا برنامه‌هایی که توسط یک ابزار مدیریت پیکربندی که از مجموع مقابله‌ها استفاده می‌کند (مانند چک‌های MD5) برای مدیریت نسخه‌های فایل انجام داد. همان‌طور که نسخه‌های جدید ویندوز دیگر آدرس‌های ثابت برای هر کتابخانه بارگذاری شده (به دلایل امنیتی) ندارند، فرصت و ارزش اتصال یک فایل اجرایی در حال کاهش است.

### پیوند صریح در زمان اجرا
فایل‌های DLL ممکن است به‌طور صریح در زمان اجرا بارگذاری شوند، یک فرایند به نام "Run-time dynamic linking" یا پیوندهای زمان اجرا توسط ماکروسافت، با استفاده از تابع `LoadLibrary` (یا `LoadLibraryEx`). تابع `GetProcAddress` برای جستجوی علامت‌های صادر شده بر اساس نام و `FreeLibrary` برای این است که DLL را بارگیری یا خالی کند. این توابع مشابه هستند با `dlopen`، `dlsym` و `dlclose` در POSIX API استاندارد.

فرایند پیوند صریح در زمان اجرا در هر زبانی که اشاره گرها به توابع را پشتیبانی می کند، یکی است. البته از آنجا که به API ویندوز بستگی دارد، نه به جای ساختارهای زبان.

### بارگیری تأخیری
به‌طور معمول، یک نرم‌افزار که در مقابله با یک کتابخانه DLL مرتبط شده، اگر DLL پیدا نشود، شروع به کار نمی‌کند؛ زیرا ویندوز برنامه را اجرا نخواهد کرد مگر آنکه بتواند تمام DLLهایی را که ممکن است برنامه به آن نیاز داشته باشد، پیدا کند. با این حال یک برنامه ممکن است در مقابله با یک کتابخانه DLL مرتبط شود تا بخواهد بارگذاری کتابخانه پویا را به تأخیر بیندازد. در این حالت سیستم عامل سعی نمی‌کند زمانی که برنامه شروع می‌شود DLL را پیدا کند یا آن را بارگذاری کند؛ در عوض، زمانی که یکی از توابع آن فراخوانده می‌شود یک خرده در نرم‌افزار به وسیلهٔ همان لینکر در نرم‌افزار اضافه شده‌است که سعی می‌کند DLL را از طریق LoadLibrary و GetProcAddress پیدا کند و آن را بارگذاری کند. اگر DLL را نتوان یافت یا بارگذاری کرد، یا تابع فراخوانده شده وجود نداشت، برنامه یک استثنا(Exception) ایجاد می‌کند که ممکن است پیدا شود و به درستی به آن رسیدگی شود. اگر برنامه به استثنائی رسیدگی نکند، توسط سیستم عامل به دام افتاده‌است که برنامه را با یک پیام خطا خاتمه می‌دهد.

مکانیزم بارگیری تأخیر دار نیز قلاب‌های اطلاع‌رسانی را فراهم می‌کند که اجازه می‌دهد برنامه پردازش‌های اضافی یا خطا در هنگام بارگذاری را هنگامی که DLL و/یا هر گونه تابع DLL ای فراخوانده شده باشد، انجام دهد.

## ملاحظات کامپایلر و زبان
### دلفی
در یک فایل منبع، به جای کلمهٔ کلیدی `program`، `library` استفاده می‌شود. در پایان فایل، توابع مورد نظر صادر شده در بند `exports` ذکر شده‌اند.

دلفی برای دسترسی به توابع از DLLها نیاز به فایل‌های `LIB` ندارد برای پیوند به یک DLL، کلمه کلیدی `external` در اعلامیه عملکرد برای نشان دادن نام DLL استفاده می‌شود، به دنبال آن `name` برای نامگذاری نماد (اگر متفاوت است) یا `index` برای شناسایی شاخص آن.

### مایکروسافت ویژوال بیسیک Microsoft Visual Basic
در ویژوال بیسیک(VB) تنها پیوند در زمان اجرا پشتیبانی می‌شود. اما علاوه بر استفاده از `LoadLibrary` و `GetProcAddress` توابع API، *اعلامیه(declare کردن)* از توابع فراخوانده شده مجاز است.

هنگام وارد کردن توابع DLL از طریق اعلان‌ها، VB یک خطای زمانی اجرا می‌کند اگر فایل `DLL` را پیدا نکند. توسعه دهنده می‌تواند خطا را دریافت و به درستی به آن رسیدگی کند.

هنگام ایجاد DLLها در VB، آن IDE تنها به شما اجازه می‌دهد تا DLLهای ActiveX را ایجاد کنید، با این حال روشهای مورد نیاز ایجاد شده که به کاربران اجازه می‌دهد تا به صراحت به لینکر بگوید که یک DEF. اضافه کند که نام هر تابع و موقعیت و عدد آن را تعریف کند. این اجازه می‌دهد تا کاربر یک DLL استاندارد ویندوز را با استفاده از ویژوال بیسیک (نسخه ۶ یا پایین‌تر) ایجاد کند که می‌تواند از طریق بیانیه "اعلام(Declare)" اشاره شود.

### C و ++ C
مایکروسافت ویژوال سی + +(MSVC) چند پسوند را برای استاندارد C ++ فراهم می‌کند که اجازه می‌دهد توابع به عنوان وارد شده یا صادر شده به‌طور مستقیم در کد سی ++مشخص شوند؛ این‌ها توسط کامپایلرهای ویندوز C و C ++، از جمله نسخه‌های ویندوز GCC بکار رفته‌است. این پسوندها از ویژگی `__declspec` قبل از اعلان تابع استفاده می‌کنند. توجه داشته باشید هنگامی که توابع C از C ++ قابل دسترسی است، آن‌ها همچنین باید به عنوان "`extern "C` در کد C ++ اعلام شوند تا کامپایلر را مطلع کنند که پیوند C باید استفاده شود.

علاوه بر مشخص کردن توابع وارد شده یا صادر شده با استفاده از ویژگی‌های `__declspec`، آن‌ها ممکن است در قسمت IMPORT یا EXPORTS از بخش `DEF` مورد استفاده در پروژه ذکر شده باشند. فایل `DEF` به جای کامپایلر، توسط لینکر پردازش شده‌است و بنابراین مختص C++ نیست.

تدوین DLL هر دو فایل `DLL` و `LIB` را تولید می‌کند. فایل `LIB` برای اتصال در مقابل یک DLL در زمان کامپایل استفاده می‌شود؛ برای پیوند زمان اجرا لازم نیست. مگر اینکه DLL شما یک مدل از شی کامپوننت - Component Object Model باشد، آنوقت فایل `DLL` باید یا در یکی از دایرکتوری‌هایی که در متغیر محدودهٔ PATH فهرست شده باشد، یا در دایرکتوری سیستم پیش فرض یا در همان دایرکتوری به عنوان برنامه ای که در حال استفاده از آن است، قرار بگیرد. DLLهای COM سرور با استفاده از regsvr32.exe ثبت می‌شوند که موقعیت مکانی DLL و شناسه جهانی آن (GUID) را در رجیستری قرار می‌دهد. سپس برنامه‌ها می‌توانند از DLLها با جستجو کردن GUID آن‌ها استفاده کنند تا مکان آن را پیدا کنند یا یک نمونه از شی COM را بسازند که به‌طور غیرمستقیم کلاس مشخص‌کنندهٔ آن و رابط مشخص‌کنندهٔ آن را استفاده کنند.

## مثال‌های برنامه‌نویسی
### استفاده از ایمپورتهای DLL
مثال‌های زیر نشان می‌دهد که چگونه از خاصیت‌های خاص زبان استفاده کنید تا نمادهایی برای پیوند در مقابل یک DLL در زمان کامپایل اضافه کنید.

**زبان دلفی** 
```delphi
{$APPTYPE CONSOLE}

program Example;

// import function that adds two numbers
function AddNumbers(a, b : Double): Double; StdCall; external 'Example.dll';

// main program
var
   R: Double;

begin
  R := AddNumbers(1, 2);
  Writeln('The result was: ', R);
end.
```
 **زبان سی**

از این که فایل پروژه Example.lib را اضافه کرده باشید، اطمینان حاصل کنید. (فرض کنید مثال Example.dll تولید شده‌است) در پروژه (اضافه کردن گزینه موجود برای پروژه!) قبل از یک پیوند استاتیک. Example.lib این فایل به صورت خودکار توسط کامپایلر در هنگام کامپایل DLL تولید می‌شود. با اجرا نکردن بخش بالا، برنامه **خطای پیوند** می‌دهد؛ زیرا لینکر نمی‌داند کجا تعریف AddNumbers را پیدا کند. شما همچنین باید DLL Example.dll را در جایی که فایل exe با کد زیر تولید می‌شود، کپی کنید. 
```c
#include <windows.h>
#include <stdio.h>

// Import function that adds two numbers
extern "C" __declspec(dllimport) double AddNumbers(double a, double b);

int main(int argc, char *argv[])
{
    double result = AddNumbers(1, 2);
    printf("The result was: %f\n", result);
    return 0;
}
```


### استفاده از پیوند صریح زمان اجرا
مثال‌های زیر نشان می‌دهد که چگونه از بارگذاری زمان اجرا و امکانات پیوند با استفاده از محدودیت‌های زبان خاص API ویندوز، استفاده کنید.

#### مایکروسافت ویژوال بیسیک
هشدار: کد زیر آسیبپذیر است، با راهنمای مایکروسافت برای بارگذاری امن یک کتابخانه مطابقت ندارد 
```vb
Option Explicit
Declare Function AddNumbers Lib "Example.dll" _
(ByVal a As Double, ByVal b As Double) As Double

Sub Main()
Dim Result As Double
Result = AddNumbers(1, 2)
Debug.Print "The result was: " & Result
End Sub
```


#### زبان دلفی
هشدار: کد زیر آسیبپذیر است، با راهنمای مایکروسافت برای بارگذاری امن کتابخانه مطابقت ندارد! 
```delphi
program Example;
  {$APPTYPE CONSOLE}
  uses Windows;
  var
  AddNumbers:function (a, b: integer): Double; StdCall;
  LibHandle:HMODULE;
begin
  LibHandle := LoadLibrary('example.dll');
  if LibHandle <> 0 then
    AddNumbers := GetProcAddress(LibHandle, 'AddNumbers');
  if Assigned(AddNumbers) then
    Writeln( '1 + 2 = ', AddNumbers( 1, 2 ) );
  Readln;
end.
```


#### زبان سی
هشدار: کد زیر آسیب‌پذیر است؛ آن را با راهنمایی مایکروسافت برای بارگذاری ایمن کتابخانه مطابقت ندارد. 
```c#
int a=0;
a++;
consol.write(a);
```


#### زبان پایتون
هشدار: کد زیر آسیب‌پذیر است؛ با راهنمایی مایکروسافت برای بارگذاری امن یک کتابخانه مطابقت ندارد! 
```python
import ctypes

my_dll = ctypes.cdll.LoadLibrary("Example.dll")
# The following "restype" method specification is needed to make
# Python understand what type is returned by the function.
my_dll.AddNumbers.restype = ctypes.c_double

p = my_dll.AddNumbers(ctypes.c_double(1.0), ctypes.c_double(2.0))

print "The result was:", p
```
 مدل Object Component (COM) یک استاندارد باینری را برای میزبانی پیاده‌سازی اشیا در DLL و EXE تعیین می‌کند. این مکانیسم‌ها برای تعیین مکان و نسخه آن فایل‌ها و همچنین توضیح زبان مستقل و قابل خواندن در ماشین از رابط فراهم می‌کند. میزبان COM اجزای در یک DLL سبک‌تر است و به آن‌ها اجازه می‌دهد که منابع را با فرایند مشتری به اشتراک بگذارند. این اجازه می‌دهد که اشیاء COM برای پیاده‌سازی پشتی‌های قدرتمند به قسمت‌های جلویی GUI ساده مانند ویژوال بیسیک و ASP. آن‌ها همچنین می‌توانند از زبان اسکریپتی برنامه‌ریزی شوند.

با توجه به آسیب‌پذیری که معمولاً به عنوان ربودن DLL شناخته می‌شود، DLL spoofing, DLL preloading یا کاوش باینری، بسیاری از برنامه‌ها DLL مخرب موجود در همان فولدر را به عنوان یک فایل داده باز شده توسط این برنامه‌ها اجرا می‌کنند. این آسیب‌پذیری توسط Georgi Guninski در سال ۲۰۰۰ کشف شد. در آگوست ۲۰۱۰، بعد از آنکه امنیت ACROS دوباره آن را کشف کرد و بعد از چندین صدها برنامه آسیب‌پذیر شد، آن را در سراسر جهان تبلیغ کرد. برنامه‌هایی که از مکان‌های ناامن اجرا می‌شوند، یعنی پوشه‌های قابل خواندن کاربر مانند *دانلودها* یا پوشه *Temp*، تقریباً همیشه به این آسیب‌پذیری حساس هستند.

## جستارهای وابسته
* Dependency Walker، یک ابزار است که توابع صادره و واردهٔ فایل‌های DLL و EXE را نشان می‌دهد
* کتابخانه پویا
* کتابخانه (محاسبات)
* لینک (محاسبات)
* لودر (محاسبات)
* Moricons.dll
* فایل شیء
* کتابخانه به اشتراک گذاشته شده
* کتابخانه استاتیک
* ِDLL hell

## پیوند به بیرون
* dllexport, dllimport در MSDN
* کتابخانه‌های دینامیک لینک در MSDN
* امنیت کتابخانه دینامیک لینک در MSDN
* سفارش جستجوی کتابخانه دینامیک لینک در MSDN
* مشاور امنیت مایکروسافت: بارگذاری کتابخانه ناامن می‌تواند اجازه اجرای کد را بدهد
* DLL چیست؟ در سایت پشتیبانی مایکروسافت
* توابع کتابخانه دینامیک لینک در MSDN
* خصوصیات فرمت فایل اجرایی قابل حمل و عمومی مشترک مایکروسافت
* مشخصات مایکروسافت برای فایل‌های DLL
* مسمومیت با بمباران فرش و دایرکتوری
* MS09-014: رفع آسیب‌پذیری بمب فرش سافاری
* اطلاعات بیشتر در مورد DLL پیش بارگذاری بردار حمله از راه دور
* یک بروزرسانی بر روی بردار حمله دور افتاده DLL-preloading
* بار کتابخانه به‌طور ایمن

## منابع
* هارت، جانسون. *ویندوز سیستم برنامه‌نویسی نسخه سوم*. Addison-Wesley، 2005. 
* رکتور، برنت و همکاران *Win32 برنامه‌نویسی*. Addison-Wesley Developers Press، ۱۹۹۷.  ISBN 0-201-63492-9. 

رده:صفحات با ترجمه بازبینی‌نشده
رده:قالب پرونده‌های رایانه‌ای
رده:کتابخانه‌های رایانه
رده:مدیریت ویندوز