Я всегда ссылаюсь на библиотеки DLL в своем коде на C #, но они остаются загадкой, которую я хотел бы прояснить. Это своего рода свалка вопросов по поводу DLL.
Я понимаю, что DLL - это динамически подключаемая библиотека, что означает, что другая программа может получить доступ к этой библиотеке во время выполнения, чтобы получить «функциональность». Однако рассмотрите следующий проект ASP.NET с Web.dll
и Business.dll
( Web.dll
это функциональность внешнего интерфейса и ссылки Business.dll
на типы и методы).
В какой момент происходит
Web.dll
динамическая ссылкаBusiness.dll
? Вы замечаете, что жесткий диск Windows часто забивается из-за, казалось бы, небольших задач при использовании Word (и т. Д.), И я считаю, что Word отключается и динамически подключается к функциям других DLL?1а. Кроме того, что загружает и связывает DLL - ОС или некую среду выполнения, такую как .NET framework?
1b. Что такое процесс «связывания»? Сделаны ли проверки совместимости? Загружается в ту же память? Что на самом деле означает связывание?
Что на самом деле выполняет код в DLL? Выполняется ли он процессором или существует еще один этап трансляции или компиляции, прежде чем процессор поймет код внутри DLL?
2а. В случае библиотеки DLL, созданной на C # .NET, на чем она работает: на платформе .NET или непосредственно в операционной системе?
Работает ли DLL из Linux в системе Windows (если такая существует), или они зависят от операционной системы?
Специфичны ли библиотеки DLL для конкретной платформы? Может ли DLL, созданная с использованием C # .NET, использоваться DLL, созданной, например, с помощью Borland C ++?
4а. Если ответ на 4 - «нет», то в чем смысл DLL? Почему различные фреймворки не используют свои собственные форматы для связанных файлов? Например: .exe, встроенный в .NET, знает, что тип файла .abc - это то, что он может связать в своем коде.
Возвращаясь к
Web.dll
/Business.dll
например - получить тип класса для клиента мне нужно ссылкиBusiness.dll
сWeb.dll
. Это должно означать, что онBusiness.dll
содержит некую спецификацию того, что на самом деле представляет собой класс клиентов. Если бы я скомпилировал свойBusiness.dll
файл, скажем, в Delphi: понял бы C # это и смог бы создать класс клиента, или есть какая-то информация заголовка или что-то такое, что говорит: «Извините, вы можете использовать меня только из другой DLL Delphi» ?5а. То же самое касается методов; Могу ли я написать
CreateInvoice()
метод в DLL, скомпилировать его на C ++, а затем получить доступ и запустить его с C #? Что мешает или позволяет мне это делать?Что касается захвата DLL, то, безусловно, заменяющая (плохая) DLL должна содержать точные сигнатуры и типы методов, как и тот, который был захвачен. Я полагаю, это было бы несложно сделать, если бы вы могли узнать, какие методы были доступны в исходной DLL.
6а. Что в моей программе на C # определяет, могу ли я получить доступ к другой DLL? Если бы моя захваченная DLL содержала те же методы и типы, что и исходная, но была скомпилирована на другом языке, сработала бы она?
Что такое импорт DLL и регистрация DLL?
Ответы:
Прежде всего, вам нужно понять разницу между двумя очень разными типами DLL. Microsoft решила использовать одни и те же расширения файлов (.exe и .dll) как с .NET (управляемый код), так и с собственным кодом, однако библиотеки DLL управляемого кода и собственные библиотеки DLL сильно отличаются внутри.
1) В случае .NET библиотеки DLL обычно загружаются по запросу, когда выполняется первый метод, пытающийся получить доступ к чему-либо из DLL. Вот почему вы можете получить исключения TypeNotFoundExceptions в любом месте своего кода, если не удается загрузить DLL. Когда что-то вроде Word внезапно начинает часто обращаться к жесткому диску, это, вероятно, происходит подкачка (получение данных, которые были выгружены на диск, чтобы освободить место в ОЗУ)
1a) В случае управляемых библиотек DLL загружается среда .NET, JIT компилирует (компилирует байт-код .NET в собственный код) и связывает библиотеки DLL. В случае собственных библиотек DLL это компонент операционной системы, который загружает и связывает DLL (компиляция не требуется, поскольку собственные библиотеки DLL уже содержат собственный код).
1b) Связывание - это когда ссылки (например, вызовы методов) в вызывающем коде на символы (например, методы) в DLL заменяются фактическими адресами объектов в DLL. Это необходимо, потому что конечные адреса вещей в DLL не могут быть известны до того, как они будут загружены в память.
2) В Windows файлы .exe и .dll совершенно идентичны. Собственные файлы .exe и .dll содержат собственный код (то же самое, что и процессор), поэтому нет необходимости переводить. Управляемые файлы .exe и .dll содержат байт-код .NET, который сначала компилируется JIT (переводится в собственный код).
2a) После JIT-компиляции кода он запускается точно так же, как и любой другой код.
3) Управляемые библиотеки DLL могут работать как есть, если фреймворки на обеих платформах обновлены и кто бы ни писал DLL, не нарушал совместимость намеренно, используя собственные вызовы. Собственные библиотеки DLL не будут работать как встроенные, поскольку их форматы различны (даже если машинный код внутри одинаков, если они предназначены для одной и той же процессорной платформы). Кстати, в Linux «DLL» известны как файлы .so (общие объекты).
4) Управляемые библиотеки DLL относятся к .NET framework, но, естественно, они работают с любым совместимым языком. Собственные библиотеки DLL совместимы, если все используют одни и те же соглашения (соглашения о вызовах (как аргументы функций передаются на уровне машинного кода), именование символов и т. Д.)
5) Управляемые библиотеки DLL содержат полное описание каждого класса, метода, поля и т. Д., Которые они содержат. AFAIK Delphi не поддерживает .NET, поэтому он будет создавать собственные библиотеки DLL, которые нельзя использовать в .NET напрямую. Вы, вероятно, сможете вызывать функции с помощью PInvoke, но определения классов не будут найдены. Я не использую Delphi, поэтому не знаю, как он хранит информацию о типах с помощью DLL. C ++, например, полагается на файлы заголовков (.h), которые содержат объявления типов и должны распространяться вместе с DLL.
6) Действительно, это не сложно, если можно легко переключить DLL. Чтобы избежать этого, можно использовать подпись кода. Чтобы кто-то мог заменить подписанную DLL, он должен знать ключ подписи, который хранится в секрете.
6a) Он будет работать, если это управляемая DLL, созданная на любом языке .NET.
«Импорт DLL» может означать многое, обычно это означает обращение к файлу DLL и использование в нем вещей.
Регистрация DLL - это то, что делается в Windows для глобальной регистрации файлов DLL как компонентов COM, чтобы сделать их доступными для любого программного обеспечения в системе.
источник
Файл .dll содержит скомпилированный код, который вы можете использовать в своем приложении.
Иногда имеет значение инструмент, используемый для компиляции .dll, иногда - нет. Если вы можете ссылаться на .dll в своем проекте, не имеет значения, какой инструмент использовался для кодирования открытых функций .dll.
Связывание происходит во время выполнения, в отличие от статически связанных библиотек, таких как ваши классы, которые связываются во время компиляции.
Вы можете думать о .dll как о черном ящике, который предоставляет вашему приложению то, что вы не хотите писать самостоятельно. Да, кто-то, понимающий подпись .dll, может создать другой .dll-файл с другим кодом внутри, и ваше вызывающее приложение не заметит разницы.
HTH
источник
1) Думаю, вы путаете линковку с загрузкой. Ссылка - это когда все системы сдержек и противовесов проверяются, чтобы убедиться, что то, о чем просят, доступно. Во время загрузки части dll загружаются в память или выгружаются в файл подкачки. Это активность HD, которую вы видите.
Динамическое связывание отличается от статического связывания тем, что при статическом связывании весь объектный код помещается в основной .exe во время связывания. При динамическом связывании объектный код помещается в отдельный файл (dll) и загружается в другое время, чем .exe.
Динамическое связывание может быть неявным (т. Е. Приложение связывается с библиотекой импорта) или явным (т. Е. Приложение использует LoadLibrary (ex) для загрузки dll).
В неявном случае / DELAYLOAD можно использовать, чтобы отложить загрузку библиотеки DLL до тех пор, пока она не понадобится приложению. В противном случае по крайней мере некоторые его части загружаются (отображаются в адресное пространство процесса) как часть инициализации процесса. DLL также может запросить, чтобы она никогда не выгружалась, пока процесс активен.
COM использует LoadLibrary для загрузки COM-библиотек. Обратите внимание, что даже в неявном случае система использует что-то похожее на LoadLibrary для загрузки dll либо при запуске процесса, либо при первом использовании.
2) DLL содержат объектный код точно так же, как .exes. Формат файла dll практически идентичен формату файла exe. Я слышал, что есть только один бит, который отличается в заголовках двух файлов.
В случае библиотеки DLL, созданной на основе C # .net, ее запускает среда .Net.
3) DLL зависят от платформы.
4) DLL могут взаимодействовать с другими фреймворками, если будут приняты особые меры или написан дополнительный связующий код.
DLL очень полезны, когда компания продает несколько продуктов, у которых есть перекрывающиеся возможности. Например, я поддерживаю растровую dll ввода-вывода, которая используется более чем 30 различными продуктами в компании. Если у вас установлено несколько продуктов, одно обновление dll может обновить все продукты до новых растровых форматов.
5) В зависимости от платформы возможности dll представлены различными способами: через файлы .h, файлы .tlb или другими способами в .net.
6) dumpbin / exports и dumbin / import - интересные инструменты для использования с .exe и .dll.
источник