Распространяются ли библиотеки C с текстовыми заголовочными файлами вместе с двоичными файлами?

#c #include #libraries

#c #включить #библиотеки

Вопрос:

Я изучаю статические и динамические библиотеки на C и как их создавать.

Одна вещь, которая продолжает меня беспокоить, это:

Предположим, что файл использует библиотеку mylibrary , выполнив #include <mylibrary.h> .

Означает ли это, что библиотеки C распространяются вместе с соответствующими файлами текстовых заголовков? Или mylibrary.h каким-то волшебным образом экспортируется из файла двоичной библиотеки?

Зависит ли это от разных подходов или от того, является ли библиотека статической или динамической?

Комментарии:

1. библиотеки поставляются с одним или несколькими файлами текстового интерфейса заголовка и двоичным (.a или .so/.dll )

2. Да, текстовые заголовочные файлы являются частью библиотеки.

3. FIY: вы не используете библиотеку с. #include <library.h> Вы используете его, когда указываете компоновщику (например gcc ... -llibrary ... ) посмотреть там. #include Сообщает компилятору, как правильно использовать код в библиотеке.

4. Я бы сказал, что если у вас есть учебник, в котором говорится: «Предположим, что файл использует библиотеку mylibrary, выполнив #include <mylibrary.h>», то вам нужен новый учебник.

Ответ №1:

Да, и в зависимости от платформы вы получаете еще больше файлов для распространения вместе с ней. Это довольно запутанная история. По крайней мере, не имеет значения, является ли библиотека статической или динамической (помимо параметров компоновщика).

Заголовочный файл необходим, поскольку скомпилированный двоичный файл не содержит достаточно информации для использования компилятором. При некоторых различиях в зависимости от платформы двоичный файл C обычно содержит достаточно метаданных только для идентификации функций и глобальных переменных по их имени. Эти метаданные не включают типы (или количество) параметров, возвращаемые типы, определения структуры или объединения, тип или размер глобальных переменных и т. Д. Вся эта информация обычно кодируется в заголовках, которые распространяются вместе с библиотекой. (Удобно, что это также означает, что все, чего нет в заголовке, скрыто от разработчика; это то, что позволяет вам создавать непубличные функции в библиотеке, которые пользователи не должны вызывать напрямую.)

На некоторых платформах двоичные файлы даже не содержат имен функций. Вместо этого на функции ссылаются по их положению в «порядковой таблице». На этих платформах библиотека должна отправлять заголовок, исполняемый двоичный файл и дополнительный файл, который преобразует имя функции в заголовке в индекс функции в порядковой таблице, так что «void hello (void)» может быть «функцией с индексом 3 в порядковой таблице таблица» компоновщику.

И наоборот, включение заголовка (обычно) не связывается с библиотекой, которую он сопровождает. Это возможно на некоторых платформах, таких как Windows, в которых есть специальные директивы компилятора, которые вы можете поместить в заголовок и которые говорят компоновщику связать с некоторой библиотекой, но это не стандартное поведение, и вы не можете ожидать, что это будет реальностью на любой другой платформе.

В разработке находятся модули, которые обеспечивают лучший пользовательский интерфейс для связи с двоичными файлами. Модуль — это еще один файл, который вы можете упаковать в свой двоичный файл с надписью «вот все мои заголовки и вот все мои библиотеки». Используя модули, можно написать что-то вроде «import MyLibrary;», и это даст вам все заголовки и все аргументы компоновщика, которые вам нужны. Я считаю, что пока нет модулей стандарта C; C добирается туда с C 20.

Комментарии:

1. Привет, спасибо за подробный ответ. Означает ли это, что в стандартные библиотеки также включен текстовый заголовок? Например, на моем компьютере с Windows у меня должна быть где-то .DLL, которая содержит двоичный код для stdio и текстовый заголовочный файл для него?

2. @AvivCohn, да. Заголовки распространяются вместе с Windows SDK, а стандартная библиотека называется примерно так ucrt.dll , и в нем есть код для каждого стандартного заголовка (не только stdio). Здесь есть еще кое-какая информация.