Що таке DLL і як це працює?


86

Я завжди посилаюся на бібліотеки DLL у своєму коді C #, але вони залишаються дещо загадкою, яку я хотів би пояснити. Це свого роду мозок запитань щодо DLL.

Я розумію, що DLL - це динамічно пов’язана бібліотека, що означає, що інша програма може отримати доступ до цієї бібліотеки під час виконання, щоб отримати "функціональність". Однак, розглянемо наступний проект ASP.NET з Web.dllта Business.dll( Web.dllце функція інтерфейсу та посилання Business.dllна типи та методи).

  1. На якому етапі Web.dllдинамічно пов’язується Business.dll? Ви помічаєте багато в обмолці жорстких дисків Windows для, здавалося б, невеликих завдань при використанні Word (тощо), і я вважаю, що Word вимикається і динамічно пов'язує функціональність з іншими бібліотеками DLL?

    1а. Крім того, що завантажує та пов'язує DLL - ОС або деякі рамки часу виконання, такі як .NET Framework?

    1б. Що таке процес «зв’язування»? Чи проводяться перевірки сумісності? Завантаження в ту саму пам’ять? Що насправді означає посилання?

  2. Що насправді виконує код у DLL? Чи виконується процесором чи існує інший етап перекладу чи компіляції, перш ніж процесор зрозуміє код всередині DLL?

    2а. У випадку DLL, вбудованої в C # .NET, що це працює: платформа .NET або операційна система безпосередньо?

  3. Чи працює DLL з Linux в системі Windows (якщо така ситуація існує), чи це конкретна операційна система?

  4. Чи є DLL специфічними для певного фреймворку? Чи може DLL, побудована за допомогою C # .NET, використовуватися DLL, побудована, наприклад, за допомогою Borland C ++?

    4а. Якщо відповідь на 4 - "ні", то який сенс у DLL? Чому різні фреймворки не використовують власні формати для пов'язаних файлів? Наприклад: .exe, вбудований у .NET, знає, що тип файлу .abc - це те, що він може зв’язати зі своїм кодом.

  5. Повертаючись до Web.dll/ Business.dllнаприклад - отримати тип класу для клієнта мені потрібно посилання Business.dllз Web.dll. Це повинно означати, що Business.dllмістить якусь специфікацію щодо того, що насправді є класом клієнта. Якби я скомпілював свій Business.dllфайл у, скажімо, Delphi: C # зрозумів би це і зміг би створити клас замовника, чи існувала якась інформація про заголовки або щось таке, що говорить "привіт, ви можете використовувати мене лише з іншої DLL-бібліотеки Delphi" ?

    5а. Те саме стосується методів; чи можу я написати CreateInvoice()метод у DLL, скомпілювати його на C ++, а потім отримати доступ і запустити його з C #? Що зупиняє або дозволяє мені це робити?

  6. Що стосується викрадення DLL, безумовно, заміна (погана) DLL повинна містити точні підписи та типи методів, як той, який викрадається. Я гадаю, це не складно було б зробити, якби ви могли дізнатися, які методи були доступні в оригінальній DLL.

    6а. Що в моїй програмі C # вирішує, чи можу я отримати доступ до іншої DLL? Якби моя викрадена DLL містила точно такі ж методи та типи, що і оригінал, але вона була скомпільована іншою мовою, чи спрацювало б це?

Що таке імпорт DLL та реєстрація DLL?


21
Це питання, можливо, вимагає найдовшої відповіді в історії SO.
Матті Вірккунен,

4
Це мали бути 12 окремих запитань.
Хенк Холтерман,

2
Це дивовижне питання, але я справді згоден з @Chaos та @Matti. Це питання потребує більшої уваги, і його можна / слід поділити на низку різних питань.
Кріс Томпсон,

3
Коли я це написав, це було трохи скиданням мозку + я хотів централізувати знання в одній області :)
Remotec

1
Наразі це має бути вікі спільноти.
леппі

Відповіді:


74

Перш за все, вам потрібно зрозуміти різницю між двома різними видами бібліотек DLL. Корпорація Майкрософт вирішила використовувати однакові розширення файлів (.exe та .dll) як із .NET (керованим кодом), так і з власним кодом, однак бібліотеки DLL із керованим кодом і власні бібліотеки DLL всередині сильно відрізняються.

1) У який момент web.dll динамічно посилається на business.dll? Ви помічаєте багато в обмолці жорстких дисків Windows для, здавалося б, невеликих завдань при використанні Word тощо, і я гадаю, що це Word вимикається і динамічно пов'язує функціональність інших DLL-файлів?

1) У випадку .NET, бібліотеки DLL зазвичай завантажуються на вимогу, коли виконується перший метод, який намагається отримати доступ до чого-небудь із DLL. Ось чому ви можете отримати TypeNotFoundExceptions де завгодно в коді, якщо DLL не вдається завантажити. Коли щось на зразок Word раптом починає багато отримувати доступ до жорсткого диска, швидше за все, відбувається обмін (отримання даних, які були замінені на диск, щоб звільнити місце в оперативній пам'яті)

1а) Додатково, що завантажує та пов'язує DLL - O / S або деякі середовища виконання, такі як .Net framework?

1а) У випадку керованих бібліотек DLL, платформа .NET - це те, що завантажується, JIT компілює (компілює байт-код .NET у власний код) і зв’язує бібліотеки DLL. У разі власних бібліотек DLL це компонент операційної системи, який завантажує та зв'язує бібліотеку DLL (компіляція не потрібна, оскільки рідна бібліотека DLL вже містить власний код).

1b) Що таке процес "зв’язування"? Чи проводиться перевірка наявності сумісності? Завантаження в ту саму пам’ять? Що насправді означає посилання?

1b) Посилання - це коли посилання (наприклад, виклики методів) у коді, що викликає, на символи (наприклад, методи) у DLL замінюються фактичними адресами речей у DLL. Це необхідно, оскільки кінцеві адреси речей у DLL не можуть бути відомі до того, як їх буде завантажено в пам'ять.

2) Що насправді виконує код у DLL? Чи виконується процесором чи існує інший етап перекладу чи компіляції, перш ніж процесор зрозуміє код всередині DLL?

2) У Windows файли .exe та .dll досить ідентичні. Власні файли .exe та .dll містять власний код (те саме, що виконує процесор), тому немає необхідності перекладати. Керовані файли .exe та .dll містять байт-код .NET, який спочатку компілюється в JIT (перекладається на рідний код).

2a) У випадку DLL, побудованої з C # .net, що це працює? Структура .Net або операційна система безпосередньо?

2a) Після компіляції коду JIT він запускається точно так само, як і будь-який інший код.

3) Чи працює бібліотека DLL від, скажімо, Linux в системі Windows (якщо така річ існує), чи це конкретна операційна система?

3) Керовані бібліотеки DLL можуть працювати як є, доки фреймворки на обох платформах оновлюються, і той, хто написав DLL, не навмисно порушив сумісність, використовуючи власні дзвінки. Власні бібліотеки DLL не працюватимуть як "всередині", оскільки формати різні (хоча машинний код всередині однаковий, якщо вони обидва для однієї платформи процесора). До речі, в Linux "бібліотеки DLL" відомі як файли .so (спільний об'єкт).

4) Чи є вони специфічними для певної системи? Чи може DLL, побудована за допомогою C # .Net, використовуватися DLL, побудована на Borland C ++ (лише приклад)?

4) Керовані бібліотеки DLL характерні для .NET framework, але, природно, вони працюють з будь-якою сумісною мовою. Власні бібліотеки DLL сумісні до тих пір, поки всі використовують однакові конвенції (конвенції викликів (як передаються аргументи функції на рівні машинного коду), іменування символів тощо)

5) Повернення до прикладу web.dll / business.dll. Щоб отримати тип клієнта класу, мені потрібно посилатися на business.dll з web.dll. Це повинно означати, що business.dll містить специфікацію свого роду того, що насправді є класом клієнта. Якби я скомпілював свій файл business.dll, скажімо, Delphi зрозумів би C # і зміг би створити клас замовника - або там є якась інформація про заголовки або щось таке, що говорить "привіт, ви можете використовувати мене лише з іншої DLL-системи delphi" .

5) Керовані бібліотеки DLL містять повний опис кожного класу, методу, поля тощо. AFAIK Delphi не підтримує .NET, тому він створює власні бібліотеки DLL, які не можна використовувати в .NET просто. Можливо, ви зможете викликати функції за допомогою PInvoke, але визначень класів не буде знайдено. Я не використовую Delphi, тому не знаю, як він зберігає інформацію про тип із бібліотеками DLL. Наприклад, C ++ покладається на файли заголовка (.h), які містять декларації типу і повинні розповсюджуватися разом з DLL.

6) Що стосується викрадення DLL, безумовно, заміна (погана) DLL повинна містити точні підписи методів, типи, як той, який викрадається. Я вважаю, це не складно зробити, якби ви змогли дізнатись, які методи тощо були доступні в оригінальній DLL.

6) Дійсно, це не важко зробити, якщо ви можете легко переключити DLL. Щоб уникнути цього, можна використовувати підпис коду. Для того, щоб хтось замінив підписану DLL, він повинен був знати ключ підписання, який він тримав у таємниці.

6a) Трохи повторення запитання тут, але це повертається до того, що в моїй програмі C # вирішує, чи можу я отримати доступ до іншої DLL? Якби моя викрадена DLL містила точно такі ж методи та типи, що і оригінал, але вона була скомпільована в іншому lanugage, чи спрацювало б це?

6a) Він буде працювати, якщо це керована DLL, створена на будь-якій мові .NET.

  • Що таке імпорт DLL? і реєстрація DLL?

"Імпорт DLL" може означати багато речей, зазвичай це означає посилання на файл DLL та використання речей у ньому.

Реєстрація DLL - це те, що робиться в Windows для глобальної реєстрації DLL-файлів як COM-компонентів, щоб зробити їх доступними для будь-якого програмного забезпечення в системі.


3
Я б додав до # 4, що .NET може перекладати бібліотеки DLL, щоб вони були сумісними з будь-якою власною програмою, яка розуміє / використовує COM (Common Object Model). Дуже хороші відповіді.
MerickOWA

7

Файл .dll містить скомпільований код, який ви можете використовувати у своїй програмі.

Іноді інструмент, який використовується для компіляції .dll, має значення, іноді ні. Якщо ви можете посилатися на .dll у своєму проекті, не має значення, який інструмент був використаний для кодування функцій, що піддаються .dll.

Посилання відбувається під час виконання, на відміну від статично пов'язаних бібліотек, таких як ваші класи, які посилаються під час компіляції.

Ви можете розглядати .dll як чорний ящик, який надає те, що потрібно вашій програмі, і що ви не хочете писати самостійно. Так, хтось, хто розуміє підпис .dll, може створити ще один файл .dll з іншим кодом всередині, і програма, що телефонує, не може знати різниці.

HTH


6

1) У який момент web.dll динамічно посилається на business.dll? Ви помічаєте багато в обмолці жорстких дисків Windows для, здавалося б, невеликих завдань при використанні Word тощо, і я гадаю, що це Word вимикається і динамічно пов'язує функціональність інших DLL-файлів?

1) Я думаю, ви плутаєте зв'язок із завантаженням. Посилання - це коли всі перевірки та противаги перевіряються, щоб переконатись, що запитуване доступне. Під час завантаження частини dll завантажуються в пам'ять або замінюються файлом сторінок. Ви бачите HD-активність.

Динамічне зв’язування відрізняється від статичного зв’язку тим, що при статичному зв’язуванні весь об’єктний код поміщається в основний .exe під час зв’язку. При динамічному зв'язуванні об'єктний код поміщається в окремий файл (dll) і завантажується в інший час, ніж .exe.

Динамічне зв’язування може бути неявним (тобто посилання на програму за допомогою бібліотеки імпорту) або явним (тобто додаток використовує LoadLibrary (ex) для завантаження dll).

У неявному випадку за допомогою / DELAYLOAD можна відкласти завантаження dll, поки програма дійсно не потребує цього. В іншому випадку принаймні деякі його частини завантажуються (відображаються в адресному просторі процесу) як частина ініціалізації процесу. DLL також може вимагати, щоб його ніколи не вивантажували, поки процес активний.

COM використовує LoadLibrary для завантаження dll-файлів COM. Зверніть увагу, що навіть у неявному випадку система використовує щось подібне до LoadLibrary для завантаження dll або під час запуску процесу, або при першому використанні.

2) Що насправді виконує код у DLL? Чи виконується процесором чи існує інший етап перекладу чи компіляції, перш ніж процесор зрозуміє код всередині DLL?

2) DLL містять об’єктний код, як і .exes. Формат файлу dll майже ідентичний формату файлу exe. Я чув, що в заголовках двох файлів є лише один біт, який відрізняється.

У випадку DLL, побудованої з C # .net, на ньому працює фреймворк .Net.

3) Чи працює бібліотека DLL від, скажімо, Linux в системі Windows (якщо така річ існує), чи це конкретна операційна система?

3) Бібліотеки DLL є специфічними для певної платформи.

4) Чи є вони специфічними для певної системи? Чи може DLL, побудована за допомогою C # .Net, використовуватися DLL, побудована на Borland C ++ (лише приклад)?

4) Dll може взаємодіяти з іншими фреймворками, якщо докласти особливої ​​уваги або написати якийсь додатковий код клею.

DLL дуже корисні, коли компанія продає кілька продуктів, що мають перекриваються можливості. Наприклад, я підтримую растровий вхід / вихід DLL, який використовується понад 30 різними продуктами компанії. Якщо у вас встановлено кілька продуктів, одне оновлення dll може оновити всі продукти до нових растрових форматів.

5) Повернення до прикладу web.dll / business.dll. Щоб отримати тип клієнта класу, мені потрібно посилатися на business.dll з web.dll. Це повинно означати, що business.dll містить специфікацію свого роду того, що насправді є класом клієнта. Якби я скомпілював свій файл business.dll, скажімо, Delphi зрозумів би C # і зміг би створити клас замовника - або там є якась інформація про заголовки або щось таке, що говорить "привіт, ви можете використовувати мене лише з іншої DLL-системи delphi" .

5) Залежно від платформи можливості DLL представлені різними способами, через .h файли, .tlb файли або іншими способами в .net.

6) Що стосується викрадення DLL, безумовно, заміна (погана) DLL повинна містити точні підписи методів, типи, як той, який викрадається. Я вважаю, це не складно зробити, якби ви змогли дізнатись, які методи тощо були доступні в оригінальній DLL.

6) dumpbin / export та dumbin / import є цікавими інструментами для використання в .exe та .dll


3) DLL є платформи конкретних
Хенк Хольтерман
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.