стемні ресурси, їх необхідно знову повернути операційній системі, вивантаживши бібліотеку з пам'яті. Для цього викликається метод FreeLibrary. При завантаженні DLL проводиться підрахунок посилань, а саме: при кожному успішному зверненні до методу LoadLibrary в DLL лічильник посилань збільшується на одиницю, а при кожному виклику методу FreeLibrary лічильник посилань зменшується на одиницю. Як тільки лічильник посилань стане рівним нулю, бібліотека вивантажується з пам'яті комп'ютера. Отже, кожному успішному викликом LoadLibrary має відповідати звернення до FreeLibrary - інакше DLL НЕ вивантажиться з пам'яті комп'ютера навіть після закінчення роботи програми. Тому дані методи були поміщені в захищений блок try ... finally .. end; - це гарантує виклик методу FreeLibrary, якщо відбувається виняток. p align="justify"> Тепер слід розглянути, яким чином завантажувана DLL розміщується в ОЗУ комп'ютера. При завантаженні DLL здійснюється резервування пам'яті, необхідний для зберігання коду методів. Крім того, резервується місце для всіх глобальних змінних і виконуються секції ініціалізації в модулях DLL. Якщо інший процес також намагається завантажити DLL, то знову відбувається резервування пам'яті для зберігання глобальних змінних. Однак копіювання методів DLL не здійснюється; також не виконується і секція ініціалізації. Іншими словами, одна копія методу в ОЗУ обслуговує кілька додатків. Глобальні змінні є унікальними для кожної програми, і якщо один додаток змінить їх значення за допомогою виклику якого-небудь методу, то інший додаток цього не помітить. Оскільки секція ініціалізації виконується тільки при першому завантаженні DLL, її не можна використовувати для установки початкових значень глобальних змінних. Вищесказане необхідно враховувати при розробці DLL. br/>
Обмін даними з DLL
DLL має загальний адресний простір з додатком, з якого викликаються його методи. З цього випливає, що покажчик на який-небудь об'єкт в пам'яті DLL є легальним всередині програми, і навпаки. Це дозволяє передати, наприклад, адреса методу або адресу даних, чого не можна зробити без використання маршрутизації при взаємодії двох додатків. Є, проте, істотна відмінність від передачі даних між двома методами одного модуля: у різних модулях різними є і диспетчери пам'яті (memory manager). Це означає, що якщо в якомусь модулі (наприклад, в DLL) був викликаний метод GetMem, то звільнити системні ресурси викликом методу FreeMem можна тільки в тому ж самому модулі. Якщо спробувати викликати метод FreeMem в додатку (для прикладу вище), то відбувається виключення. Оскільки при створенні екземплярів класу також відбувається звернення до диспетчера пам'яті, то їх деструктори не можна викликати за межами модуля. Зокрема, якщо в DLL відбувається виключення, то створюється об'єкт в диспетчері пам'яті DLL. Якщо не використовувати пастки винятків, то цей об'єкт п...