В информатике библиотека — это совокупность ресурсов , которая используется в процессе разработки программного обеспечения для реализации компьютерной программы .
Исторически библиотека состояла из подпрограмм (сегодня их обычно называют функциями). Теперь эта концепция включает в себя другие формы исполняемого кода, включая классы и неисполняемые данные, включая изображения и текст . Она также может относиться к коллекции исходного кода .
Например, программа может использовать библиотеку для косвенного выполнения системных вызовов вместо того, чтобы выполнять эти системные вызовы непосредственно в программе.
Библиотека может использоваться несколькими независимыми потребителями (программами и другими библиотеками). Это отличается от ресурсов, определенных в программе, которые обычно могут использоваться только этой программой.
Когда потребитель использует ресурс библиотеки, он получает ценность библиотеки без необходимости реализовывать ее самостоятельно. Библиотеки поощряют повторное использование кода в модульной форме.
При написании кода, использующего библиотеку, программисту необходимо знать только общую информацию, например, какие элементы она содержит и как их использовать, а не все внутренние детали библиотеки.
Библиотеки могут использовать другие библиотеки, что приводит к образованию иерархии библиотек в программе.
Библиотека исполняемого кода имеет четко определенный интерфейс , с помощью которого вызывается функциональность. Например, в C функция библиотеки вызывается с помощью обычной возможности вызова функции C. Компоновщик генерирует код для вызова функции с помощью библиотечного механизма, если функция доступна из библиотеки, а не из самой программы. [1]
Функции библиотеки могут быть подключены к вызывающей программе на разных этапах жизненного цикла программы . Если доступ к коду библиотеки осуществляется во время сборки вызывающей программы, то библиотека называется статической библиотекой . [2] Альтернативой является сборка исполняемого файла программы отдельно от файла библиотеки. Функции библиотеки подключаются после запуска исполняемого файла, либо во время загрузки , либо во время выполнения . В этом случае библиотека называется динамической библиотекой .
Большинство компилируемых языков имеют стандартную библиотеку , хотя программисты также могут создавать свои собственные пользовательские библиотеки. Большинство современных систем программного обеспечения предоставляют библиотеки, которые реализуют большинство системных служб. Такие библиотеки организовали службы, которые требуются современному приложению. Таким образом, большая часть кода, используемого современными приложениями, предоставляется в этих системных библиотеках.
Идея компьютерной библиотеки восходит к первым компьютерам, созданным Чарльзом Бэббиджем . В статье 1888 года о его аналитической машине предполагалось, что компьютерные операции могут быть пробиты на отдельных картах с числового ввода. Если бы эти операционные перфокарты сохранялись для повторного использования, то «постепенно машина имела бы свою собственную библиотеку». [3]
В 1947 году Голдстайн и фон Нейман предположили, что было бы полезно создать «библиотеку» подпрограмм для их работы на машине IAS , раннем компьютере, который в то время еще не был в рабочем состоянии. [4] Они представили себе физическую библиотеку записей на магнитных проводах , где каждый провод хранил бы повторно используемый компьютерный код. [5]
Вдохновленные фон Нейманом, Уилкс и его команда сконструировали EDSAC . В картотеке из перфоленты хранилась библиотека подпрограмм для этого компьютера. [6] Программы для EDSAC состояли из основной программы и последовательности подпрограмм, скопированных из библиотеки подпрограмм. [7] В 1951 году команда опубликовала первый учебник по программированию, «Подготовка программ для электронного цифрового компьютера» , в котором подробно описывалось создание и назначение библиотеки. [8]
В 1959 году COBOL включал в себя «примитивные возможности библиотечной системы» [9] , но Жан Саммет охарактеризовал их как «неадекватные библиотечные возможности» в ретроспективе [10] .
В JOVIAL есть коммуникационный пул (COMPOOL), представляющий собой библиотеку заголовочных файлов.
Другим важным фактором в современной концепции библиотеки стала инновация подпрограмм FORTRAN . Подпрограммы FORTRAN могут быть скомпилированы независимо друг от друга, но компилятору не хватало компоновщика . Поэтому до введения модулей в Fortran-90 проверка типов между подпрограммами FORTRAN [NB 1] была невозможна. [11]
К середине 1960-х годов библиотеки копирования и макросов для ассемблеров стали обычным явлением. Начиная с популярности IBM System/360 , библиотеки, содержащие другие типы текстовых элементов, например, системные параметры, также стали обычным явлением.
В системе OS/360 компании IBM и ее последователях это называется секционированным набором данных .
Первый объектно-ориентированный язык программирования Simula , разработанный в 1965 году, поддерживал добавление классов в библиотеки через свой компилятор. [12] [13]
Библиотеки играют важную роль в процессе связывания или привязки программ , который разрешает ссылки, известные как ссылки или символы, на библиотечные модули. Процесс связывания обычно автоматически выполняется программой -линкером или связующим, которая ищет набор библиотек и других модулей в заданном порядке. Обычно это не считается ошибкой, если цель ссылки может быть найдена несколько раз в заданном наборе библиотек. Связывание может быть выполнено при создании исполняемого файла (статическое связывание) или всякий раз, когда программа используется во время выполнения (динамическое связывание).
Разрешаемые ссылки могут быть адресами для переходов и других стандартных вызовов. Они могут быть в основной программе или в одном модуле, зависящем от другого. Они разрешаются в фиксированные или перемещаемые адреса (из общей базы) путем выделения памяти времени выполнения для сегментов памяти каждого ссылаемого модуля.
Некоторые языки программирования используют функцию, называемую умной компоновкой , посредством которой компоновщик знает или интегрирован с компилятором, так что компоновщик знает, как используются внешние ссылки, и код в библиотеке, который фактически никогда не используется , даже если на него есть внутренние ссылки, может быть удален из скомпилированного приложения. Например, программа, которая использует только целые числа для арифметики или вообще не выполняет арифметических операций, может исключить библиотечные процедуры с плавающей точкой. Эта функция умной компоновки может привести к уменьшению размера файла приложения и сокращению использования памяти.
Некоторые ссылки в модуле программы или библиотеки хранятся в относительной или символической форме, которая не может быть разрешена, пока всему коду и библиотекам не будут назначены окончательные статические адреса. Перемещение — это процесс корректировки этих ссылок, который выполняется либо компоновщиком, либо загрузчиком . В общем случае перемещение не может быть выполнено для отдельных библиотек, поскольку адреса в памяти могут различаться в зависимости от программы, использующей их, и других библиотек, с которыми они объединены. Позиционно-независимый код избегает ссылок на абсолютные адреса и, следовательно, не требует перемещения.
Когда связывание выполняется во время создания исполняемого файла или другого объектного файла, это известно как статическое связывание или раннее связывание . В этом случае связывание обычно выполняется компоновщиком , но может также выполняться компилятором . [ 14] Статическая библиотека , также известная как архив , — это библиотека, предназначенная для статической компоновки. Первоначально существовали только статические библиотеки. Статическое связывание должно выполняться при перекомпиляции любых модулей.
Все модули, необходимые программе, иногда статически связываются и копируются в исполняемый файл. Этот процесс и полученный в результате автономный файл известны как статическая сборка программы. Статическая сборка может не нуждаться в дальнейшем перемещении , если используется виртуальная память и не требуется рандомизация макета адресного пространства . [15]
Разделяемая библиотека или разделяемый объект — это файл, который предназначен для совместного использования исполняемыми файлами и другими разделяемыми объектными файлами . Модули, используемые программой, загружаются из отдельных разделяемых объектов в память во время загрузки или выполнения , а не копируются компоновщиком, когда он создает единый монолитный исполняемый файл для программы.
Общие библиотеки могут быть статически связаны во время компиляции, что означает, что ссылки на модули библиотеки разрешаются, а модули выделяют память при создании исполняемого файла. [ необходима цитата ] Но часто связывание общих библиотек откладывается до тех пор, пока они не будут загружены. [ сомнительно – обсудить ]
Хотя изначально динамическое связывание было впервые применено в 1960-х годах, оно не достигло наиболее часто используемых операционных систем до конца 1980-х годов. Оно было доступно в той или иной форме в большинстве операционных систем к началу 1990-х годов. В этот же период объектно-ориентированное программирование (ООП) стало важной частью ландшафта программирования. ООП с привязкой во время выполнения требует дополнительной информации, которую традиционные библиотеки не предоставляют. В дополнение к именам и точкам входа кода, расположенного внутри, им также требуется список объектов, от которых они зависят. Это побочный эффект одной из основных концепций ООП, наследования, что означает, что части полного определения любого метода могут находиться в разных местах. Это больше, чем просто перечисление того, что одна библиотека требует услуг другой: в настоящей системе ООП сами библиотеки могут быть неизвестны во время компиляции и различаться от системы к системе.
В то же время многие разработчики работали над идеей многоуровневых программ, в которых «дисплей», работающий на настольном компьютере, использовал бы сервисы мэйнфрейма или мини -компьютера для хранения или обработки данных. Например, программа на компьютере с графическим интерфейсом отправляла бы сообщения на мини-компьютер, чтобы вернуть небольшие образцы огромного набора данных для отображения. Удаленные вызовы процедур (RPC) уже справлялись с этими задачами, но стандартной системы RPC не было.
Вскоре большинство поставщиков мини-компьютеров и мэйнфреймов инициировали проекты по объединению этих двух, создавая формат библиотеки ООП, который можно было бы использовать где угодно. Такие системы были известны как библиотеки объектов или распределенные объекты , если они поддерживали удаленный доступ (не все это делали). COM от Microsoft является примером такой системы для локального использования. DCOM, модифицированная версия COM, поддерживает удаленный доступ.
Некоторое время объектные библиотеки имели статус «следующей большой вещи» в мире программирования. Было предпринято несколько попыток создать системы, которые работали бы на разных платформах, и компании соревновались, пытаясь запереть разработчиков в их собственной системе. Примерами служат System Object Model (SOM/DSOM) от IBM , Distributed Objects Everywhere (DOE) от Sun Microsystems , Portable Distributed Objects (PDO) от NeXT , ObjectBroker от Digital , Component Object Model (COM/DCOM) от Microsoft и множество систем на основе CORBA .
Библиотеки классов являются грубым эквивалентом ООП старых типов библиотек кода. Они содержат классы , которые описывают характеристики и определяют действия ( методы ), которые включают объекты. Библиотеки классов используются для создания экземпляров или объектов, характеристики которых установлены в определенные значения. В некоторых языках ООП, таких как Java , различие очевидно: классы часто содержатся в файлах библиотек (например, в формате JAR-файла Java ), а экземпляры объектов находятся только в памяти (хотя потенциально могут быть сделаны постоянными в отдельных файлах). В других, таких как Smalltalk , библиотеки классов являются просто отправной точкой для образа системы , который включает в себя все состояние среды, классов и всех экземпляров объектов.
Сегодня большинство библиотек классов хранятся в репозитории пакетов (например, Maven Central для Java). Клиентский код явно объявляет зависимости от внешних библиотек в файлах конфигурации сборки (например, Maven Pom в Java).
Другая библиотечная техника использует полностью отдельные исполняемые файлы (часто в некоторой облегченной форме) и вызывает их с помощью удаленного вызова процедур (RPC) по сети на другой компьютер. Это максимизирует повторное использование операционной системы: код, необходимый для поддержки библиотеки, — это тот же код, который используется для обеспечения поддержки приложений и безопасности для каждой другой программы. Кроме того, такие системы не требуют, чтобы библиотека существовала на той же машине, но могут пересылать запросы по сети.
Однако такой подход означает, что каждый вызов библиотеки требует значительных накладных расходов. Вызовы RPC намного дороже, чем вызов общей библиотеки, которая уже загружена на ту же машину. Этот подход обычно используется в распределенной архитектуре , которая интенсивно использует такие удаленные вызовы, в частности, в клиент-серверных системах и серверах приложений , таких как Enterprise JavaBeans .
Библиотеки генерации кода — это высокоуровневые API , которые могут генерировать или преобразовывать байт-код для Java . Они используются аспектно-ориентированным программированием , некоторыми фреймворками доступа к данным и для тестирования для генерации динамических прокси-объектов. Они также используются для перехвата доступа к полям. [16]
Система хранит libfoo.a
и libfoo.so
файлы в каталогах, таких как /lib
, /usr/lib
или /usr/local/lib
. Имена файлов всегда начинаются с lib
, и заканчиваются суффиксом .a
( архив , статическая библиотека) или .so
(общий объект, динамически связанная библиотека). В некоторых системах может быть несколько имен для динамически связанной библиотеки. Эти имена обычно имеют один и тот же префикс и разные суффиксы, указывающие номер версии. Большинство имен являются именами для символических ссылок на последнюю версию. Например, в некоторых системах libfoo.so.2
будет именем файла для второй основной версии интерфейса динамически связанной библиотеки libfoo
. .la
Файлы, которые иногда находятся в каталогах библиотек, являются архивами libtool , которые не могут использоваться системой как таковые.
Система наследует соглашения о статических библиотеках от BSD , при этом библиотека хранится в .a
файле, и может использовать .so
динамически подключаемые библиотеки в стиле -style (с .dylib
суффиксом вместо этого). Однако большинство библиотек в macOS состоят из «фреймворков», размещенных внутри специальных каталогов, называемых « комплектами », которые оборачивают требуемые файлы и метаданные библиотеки. Например, фреймворк с именем MyFramework
будет реализован в комплекте с именем MyFramework.framework
, который MyFramework.framework/MyFramework
будет либо файлом динамически подключаемой библиотеки, либо символической ссылкой на файл динамически подключаемой библиотеки в MyFramework.framework/Versions/Current/MyFramework
.
Динамически подключаемые библиотеки обычно имеют суффикс *.DLL
, [17] , хотя другие расширения имен файлов могут идентифицировать динамически подключаемые библиотеки специального назначения, например, *.OCX
библиотеки OLE . Изменения интерфейса либо кодируются в именах файлов, либо абстрагируются с помощью интерфейсов COM-объектов . В зависимости от того, как они компилируются, *.LIB
файлы могут быть либо статическими библиотеками, либо представлениями динамически подключаемых библиотек, необходимых только во время компиляции, известными как « библиотеки импорта ». В отличие от мира UNIX , где используются различные расширения файлов, при связывании с .LIB
файлом в Windows сначала нужно узнать, является ли это обычной статической библиотекой или библиотекой импорта. В последнем случае .DLL
файл должен присутствовать во время выполнения.
вероятно, будет очень важно разработать обширную «библиотеку» подпрограмм
Библиотека генерации байт-кода — это высокоуровневый API для генерации и преобразования байт-кода JAVA. Используется в АОП, тестировании, фреймворках доступа к данным для генерации динамических прокси-объектов и перехвата доступа к полям.
Общие библиотеки Linux похожи на динамически подключаемые библиотеки (DLL) Windows. DLL Windows обычно идентифицируются по .dll
расширениям имен файлов.