C / C ++: В чем разница между статически связанной библиотекой и объектным файлом?

Я понимаю, что код, включенный в исполняемый файл во время компиляции, может поступать из объектных файлов (файлы .o) и статически связанных библиотек (файлы .lib / .a). В чем принципиальная и концептуальная разница между этими двумя? Почему существует различное понятие между «объектным кодом» и «статически связанной библиотекой»? В чем преимущества и недостатки каждого из них и почему использовать одно вместо другого? Можно ли создать статически связанную библиотеку (-ы) из объектного (-ых) файла (-ов), и, наоборот, можно ли создать объектный файл (-ы) из статически-связанной библиотеки (-ий)?


person user553702    schedule 01.05.2013    source источник


Ответы (2)


Объектные файлы скомпилированы, но код не привязан. Библиотеки содержат объектные файлы. Таким образом, возникает вопрос: «Зачем использовать статически связанные библиотеки, если я могу просто использовать объектные файлы?» Вот почему.

В отличие от коллекции объектов, каждый из которых имеет свои собственные таблицы символов, библиотека имеет единую унифицированную таблицу символов, которая создается, когда ar вызывается разработчиком библиотеки с помощью переключателя s. s вызывает ranlib для создания единой таблицы символов для всех объектов в этом архиве.

Запуск ranlib в оболочке отображается в первой строке текста справки:

Создайте индекс для ускорения доступа к архивам.

И из общих документов ranlib:

Архив с таким индексом ускоряет связывание с библиотекой и позволяет подпрограммам в библиотеке вызывать друг друга независимо от их размещения в архиве. Т

См. Также документы Runlib FreeBSD - другая формулировка, та же идея: Скорость привязки.

person Engineer    schedule 05.07.2015

Библиотека - это просто файл, содержащий множество объектных файлов, в которых можно искать символы.

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

Когда вы передаете библиотеку компоновщику, он проверяет каждый из объектных файлов в ней и вводит те, которые необходимы для удовлетворения неразрешенных символов (и, вероятно, продолжит вводить их, пока не будут разрешены все символы или больше не будет) .

Это просто способ эффективно упаковать множество объектов в один файл, чтобы компоновщик мог выполнять больше вашей работы - вам не нужно беспокоиться о том, какие объекты вам нужны.

Если вы думаете о библиотеке C, у вас может быть printf.o, puts.o, fopen.o в результате того, что ваш источник хорошо разделен. Вы не хотите, чтобы пользователь явно перечислял каждый отдельный объектный файл, который ему нужен, поэтому вы упаковываете все это в libc.a и говорите им, что им просто нужно связать с этим единственным файлом.


Статически связанный бит здесь не имеет значения, он просто решает, что объекты должны переходить в исполняемый файл во время компоновки, а не загружаться динамически во время выполнения. Это объясняется здесь.

person paxdiablo    schedule 01.05.2013
comment
Итак, почему есть разница в эффективности или объеме работы, которую пользователь должен выполнить при использовании файла библиотеки, а не одного или нескольких объектных файлов? Разве компоновщик не может всегда оптимизировать? И если статически связанные библиотеки представляют собой набор объектных файлов, то загружает ли он каждый объектный субфайл по принципу «все или ничего» или только те символы, которые используются? У вас есть пример того, как возникнут существенные различия при создании исполняемого файла из одного и того же кода в зависимости от того, происходит ли этот код из статически связанной библиотеки или объектного файла (ов)? - person user553702; 01.05.2013
comment
@ user553702, вы хотите перечислить восемьдесят пять различных объектных файлов, некоторые из которых даже не нужны, или вы бы предпочли просто перечислить libc.a и позволить компоновщику работать над этим? Может быть, я по своей природе ленив, но это не всегда плохо :-) Что касается того, как работает компоновщик, он может выбросить те, которые не удовлетворяют никаким символам, даже если вы явно перечислите их. Большинство из них этого не делает, хотя ISTR Visual Studio была такой умной. - person paxdiablo; 01.05.2013
comment
Большинство компоновщиков извлекают из библиотеки только те объектные файлы, которые им нужны (и все каждого объектного файла, который они сочтут нужным) для простоты. - person paxdiablo; 01.05.2013