DLL и LIB файлы - что и почему?

214

Я очень мало знаю о DLL и LIB, кроме того, что они содержат жизненно важный код, необходимый для правильной работы программы - библиотеки. Но почему компиляторы генерируют их вообще? Не будет ли проще просто включить весь код в один исполняемый файл? И в чем разница между DLL и LIB?

Xonara
источник

Ответы:

299

Существуют статические библиотеки (LIB) и динамические библиотеки (DLL), но обратите внимание, что файлы .LIB могут быть либо статическими библиотеками (содержащими объектные файлы), либо библиотеками импорта (содержащими символы, позволяющие компоновщику связываться с DLL).

Библиотеки используются потому, что у вас может быть код, который вы хотите использовать во многих программах. Например, если вы напишите функцию, которая подсчитывает количество символов в строке, эта функция будет полезна во многих программах. Как только вы получите правильную работу этой функции, вам не нужно будет перекомпилировать код каждый раз, когда вы ее используете, поэтому вы помещаете исполняемый код этой функции в библиотеку, и компоновщик может извлечь и вставить скомпилированный код в вашу программу. , По этой причине статические библиотеки иногда называют «архивами».

Динамические библиотеки делают еще один шаг вперед. Кажется расточительным иметь несколько копий библиотечных функций, занимающих место в каждой из программ. Почему они не могут поделиться одной копией функции? Для этого и нужны динамические библиотеки. Вместо того, чтобы встраивать библиотечный код в вашу программу при ее компиляции, его можно запустить, сопоставив его с вашей программой по мере загрузки в память. Несколько одновременно работающих программ, использующих одни и те же функции, могут совместно использовать одну копию, экономя память. Фактически, вы можете загружать динамические библиотеки только по мере необходимости, в зависимости от пути через ваш код. Нет смысла заставлять принтер загружать память, если вы не печатаете. С другой стороны, это означает, что вы должны иметь копию динамической библиотеки, установленной на каждом компьютере, на котором работает ваша программа.

Например, почти каждая программа, написанная на «C», будет нуждаться в функциях из библиотеки, называемой «C runtime library», хотя немногим программам понадобятся все функции. Среда выполнения C поставляется в статической и динамической версиях, поэтому вы можете определить, какую версию использует ваша программа, в зависимости от конкретных потребностей.

Чарльз Э. Грант
источник
81
Оказывается, что .LIBфайлы могут быть статическими библиотеками (содержащими объектные файлы) или библиотеками импорта (содержащими символы, позволяющие компоновщику связываться с DLL). Мне интересно, почему это так.
Луми
2
хорошее объяснение! Код является общим, и данные (по умолчанию) не передаются между приложениями, использующими Dll.
Мокс
4
@Lumi: Хороший вопрос. С точки зрения DLL у нас есть два типа ссылок. Неявные ссылки , когда у нас есть .libфайл, предоставленный создателем DLL вместе с соответствующими заголовками; это .libпросто дескриптор целевой DLL, он содержит адреса, точку входа и т. д., но не содержит кода. Это .libдолжно быть передано компоновщику. Второй - явное связывание, когда мы используем DLL, вручную загружая ее с помощью LoadLibraryфункции. В этом типе нам не нужен этот .libфайл, но мы должны приложить немного усилий, чтобы найти экспорты DLL, их адреса и вызвать эти функции через указатели.
Итачи
37

Другим аспектом является безопасность (обфускация). После того, как фрагмент кода извлечен из основного приложения и помещен в «отдельную» библиотеку Dynamic-Link, легче атаковать, анализировать (анализировать) код, поскольку он был изолирован. Когда тот же фрагмент кода хранится в библиотеке LIB, он является частью скомпилированного (связанного) целевого приложения, и, таким образом, сложнее отделить (дифференцировать) этот фрагмент кода от остальных целевых двоичных файлов.

MOX
источник
Аспект безопасности был для меня новым. Остаются ли приведенные выше рассуждения верными в случае, когда приложение C # вызывает нативный неуправляемый C ++ dll?
Мартин
1
Но LIB тоже изолирован, не так ли? Таким образом, злоумышленник может просто проанализировать LIB. Или это распространенный сценарий, когда LIB недоступен для общественности?
Ник Расслер
8
LIB тоже «изолирован», что касается процесса компиляции, но как только компоновщик соберет части вместе, LIB станет частью EXE и его нельзя будет отличить от вашего собственного кода.
Мокс
17

Одной из важных причин создания DLL / LIB, а не просто компиляции кода в исполняемый файл, является повторное использование и перемещение. Обычное приложение Java или .NET (например), скорее всего, будет использовать несколько сторонних (или каркасных) библиотек. Гораздо проще и быстрее просто скомпилировать предварительно созданную библиотеку, чем скомпилировать весь сторонний код в ваше приложение. Компиляция вашего кода в библиотеки также поощряет хорошие методы проектирования, например, разработку ваших классов для использования в различных типах приложений.

Энди Уайт
источник
7

DLL - это библиотека функций, которые совместно используются другими исполняемыми программами. Просто загляните в ваш каталог windows / system32, и вы найдете десятки из них. Когда ваша программа создает DLL, она также обычно создает файл lib, чтобы программа * .exe приложения могла разрешать символы, объявленные в DLL.

.Lib - это библиотека функций, которые статически связаны с программой - они НЕ являются общими для других программ. Каждая программа, которая связана с файлом * .lib, имеет весь код в этом файле. Если у вас есть две программы A.exe и B.exe, которые связаны с C.lib, то каждая из A и B будет содержать код в C.lib.

То, как вы создаете библиотеки DLL и библиотеки, зависит от того, какой компилятор вы используете. Каждый компилятор делает это по-своему.

Винодхини Рамасами
источник
4

Еще одно отличие заключается в производительности.

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

С другой стороны, .lib - это код, который статически связан во время компиляции с каждым запрашивающим процессом. Следовательно, .exe (ы) будут иметь одну память, таким образом увеличивая производительность процесса.

Гириш Реддивари
источник