Что находится в 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?

    1b. Что такое процесс «связывания»? Сделаны ли проверки совместимости? Загружается в ту же память? Что на самом деле означает связывание?

  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?

Remotec
источник
21
Этот вопрос вполне может быть запросом на самый длинный ответ в истории SO.
Матти Вирккунен
4
Должно было быть 12 отдельных вопросов.
Хенк Холтерман,
2
Это отличный вопрос, но я действительно согласен с @Chaos и @Matti. Этот вопрос требует более пристального внимания и может / должен быть разделен на несколько разных вопросов.
Крис Томпсон,
3
Когда я писал это, это было чем-то вроде свалки мозгов + я хотел централизовать знания в одной области :)
Remotec
1
К настоящему времени должна быть вики сообщества.
leppie

Ответы:

74

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

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

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

1a) Кроме того, что загружает и связывает DLL - O / S или некоторую среду выполнения, такую ​​как .Net framework?

1a) В случае управляемых библиотек DLL загружается среда .NET, JIT компилирует (компилирует байт-код .NET в собственный код) и связывает библиотеки DLL. В случае собственных библиотек DLL это компонент операционной системы, который загружает и связывает DLL (компиляция не требуется, поскольку собственные библиотеки DLL уже содержат собственный код).

1б) Что такое процесс «связывания»? Проверяется ли совместимость? Загружается в ту же память? Что на самом деле означает связывание?

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 # и смог бы создать класс клиента - или есть какая-то информация заголовка или что-то такое, что говорит: «Извините, вы можете использовать меня только из другой библиотеки 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 содержала те же методы и типы, что и исходная, но была скомпилирована на другом языке, сработала бы она?

6a) Он будет работать, если это управляемая DLL, созданная на любом языке .NET.

  • Что такое импорт DLL? а dll оформление?

«Импорт DLL» может означать многое, обычно это означает обращение к файлу DLL и использование в нем вещей.

Регистрация DLL - это то, что делается в Windows для глобальной регистрации файлов DLL как компонентов COM, чтобы сделать их доступными для любого программного обеспечения в системе.

Матти Вирккунен
источник
3
Я бы добавил к № 4, что .NET может переводить библиотеки DLL, чтобы они были совместимы с любой собственной программой, которая понимает / использует COM (Common Object Model). Очень хорошие ответы.
MerickOWA 02
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 для загрузки 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 # и смог бы создать класс клиента - или есть какая-то информация заголовка или что-то такое, что говорит: «Извините, вы можете использовать меня только из другой библиотеки delphi» .

5) В зависимости от платформы возможности dll представлены различными способами: через файлы .h, файлы .tlb или другими способами в .net.

6) Что касается захвата DLL, конечно, заменяющая (плохая) DLL должна содержать точные сигнатуры методов, типы которых соответствуют захваченной. Я полагаю, это было бы несложно сделать, если бы вы могли узнать, какие методы и т. Д. Были доступны в исходной DLL.

6) dumpbin / exports и dumbin / import - интересные инструменты для использования с .exe и .dll.

Edgman
источник
3) DLL являются платформы конкретных
Хенк Хольтерман