| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Анатомия библиотек |
| Автор: Kroll 28.9.2014, 11:14 | ||
| Вопрос скорее более фундаментальный и должен быть в разделе C/C++, если не ещё выше, но у меня он возник в контексте Qt. И так, что я знаю. Существует два вида библиотек: статические и разделяемые (динамические). 1) Статическая библиотека Это объектные бинарники, которые после компиляции склеиваются в один файл с расширением .lib или .a. Потом этот файл может быть подставлен в другой проект на этапе линковки вместе с заголовочником и вкомпилен намертво как равноправный с родными объектными файлами этого проекта в конечный исполняемый файл программы. Т.е. по большому счёту статическая библиотека - это обыкновенные объектники. Здесь в основном не понятно, какая информация добавляется в библиотечный архив кроме самих объектных файлов. Ну и ещё про то, можно ли статическую библиотеку подключать, написанную на другом языке. 2) Динамическая библиотека Это архив объектников скомпиленный в .dll или .so с каким-то системным файликом, который позволяет системе подгружать динамическую библиотеку в оперативную память при поступлении запроса. Файл динамической библиотеки всегда существует отдельно от исполняемых программ, которые им пользуются. У динамической библиотеки есть некая таблица экспортируемых символов (если я правильно помню название), в которую вносятся так называемые символы - внутренние библиотечные переменные, функции и классы, которые будут видны для использующих библиотеку программ. Для динамической библиотеки есть два варианта подключения (или импорта) в использующую программу. Первый вариант - раннее связывание (или статический импорт). Ключевое отличие - библиотека подключается на этапе запуска программы и находится в памяти как минимум до завершения её работы. Второй вариант - позднее связывание (или динамический импорт). В этом случае в программе во время выполнения можно подключать и отключать библиотеку через запросы к системе в нужный момент. В Qt этим занимается QLibrary. Вот здесь больше непонятностей. Например, чем всё-таки отличаются механизмы этих вариантов подключения? Первоначально создалось впечатление, что статический импорт это динамический: тем же способом подключается, но один раз при запуске. А потом где-то краем глаза прочитал, что вроде как при компиляции программы в неё включается вроде как файл (почемуто .lib) с таблицей экспортируемых функций и соответствия проверяются на этапе линковки, а только сам вызов на этапе выполнения. Очень не понятен этот момент. Вот http://qt-project.org/wiki/How_to_create_a_library_with_Qt_and_use_it_in_an_application_Russian пишут:
Откуда тут .lib? Я при сборке имею только заголовочники .h и собственно библиотечный файл. И всё потом работает. В общем очень замутная эта тема с библиотеками. И главное, прочитать об этом достоверно в одном месте не найти где. Знатоки, гуру, просветите пожалуйста. |
| Автор: math64 29.9.2014, 07:29 |
| 1. Как отдельный объектный файл, так и статическая библиотека, так и динамическая библиотека, могут быть написаны на другом языке, если соблюдаются соглашения о передаче параметров и другие соответствия. Труднее подключить библиотеку, написанную на C++, но скомпилированную другим компилятором или другой версиий того же компилятора, используюго другую версию runtime библиотеки. 2. Для раннего связывания нужна кроме dll ещё библиотека импорта. 3. При позднем связывании, кроме подключения dll, нужно найти точки входа. Точки входа обычно объявляются extern "C", чтобы её имя не изменялось (имя обычной функции изменяется и содержит информацию о параметрах; разные компиляторы именят имя по-разному). 4. При позднем связывании невозможно вызвать inline функции - их нет в dll. Применение шаблонов тоже ограничено. |
| Автор: Kroll 29.9.2014, 10:47 |
| А где обо всём этом можно подробней прочитать? |
| Автор: borisbn 29.9.2014, 11:04 |
В принципе - ничем. Просто в первом варианте за тебя всё делает компилятор/линковщик. Они по h-файлу генерят код с LoadLibrary и GetProcAddress (для linux - dlLoad, кажется). Но такой вариант неприемлем, если тебе нужно организовать систему плагинов, т.е. если в разных dll-ках находятся одинаковые по интерфейсу функции, и набор dll-ек неизвестен на этапе компиляции/линковки. |