почему мне нужно связать файл lib с моим проектом? - PullRequest
9 голосов
/ 05 августа 2011

Я создаю проект, который использует DLL. Чтобы построить мой проект, мне нужно включить заголовочный файл и файл lib. Почему мне нужно включить соответствующий файл lib? не должен ли заголовочный файл объявлять всю необходимую информацию, а затем во время выполнения загружать любую необходимую библиотеку / dll?

Спасибо

Ответы [ 7 ]

3 голосов
/ 05 августа 2011

Нет, файл заголовка не всегда достаточно.Заголовочный файл может содержать только объявления функций и классов и других необходимых вам вещей, , а не их реализации.

Существует большой разрыв между этим кодом:

void Multiply(int x, int y);

и этот код:

void Multiply(int x, int y)
{
   return x * y;
}

Первый - это объявление, а второй - определение или реализация.Обычно первый пример помещается в заголовочные файлы, а второй - в файлы .CPP (если вы создаете библиотеки).Если вы включили заголовок с первым и ничего не связали, как ваше приложение должно знать, как реализовать Multiply?

Теперь, если вы используете файлы заголовков, которые содержат код, который ВСЕМ встроен, тоВам не нужно ничего связывать.Но если хотя бы один метод НЕ является встроенным, но имеет реализацию в файле .CPP, скомпилированном в файл .lib, тогда вам нужно будет связать его в файле .lib.

[ПРАВИТЬ] При использованииИмпортируйте библиотеки, вы говорите компоновщику НЕ включать детали реализации импортированного кода в ваш двоичный файл.Вместо этого ОС будет загружать DLL импорта во время выполнения в ваш процесс.Это уменьшит размер вашего приложения, но вам придется поставлять с ним еще одну DLL.Если реализация библиотеки изменится, вы можете просто переназначить другую DLL своим клиентам, и вам не нужно будет переустанавливать все приложение целиком.

Есть еще один вариант, когда вы можете просто связать библиотеку, а вы ненужно отправить еще одну DLL.В этом варианте компоновщик будет включать реализацию в ваше приложение, увеличивая его размер.Если вам нужно изменить детали реализации в импортированной библиотеке, то вам придется перекомпилировать и заново связать все ваше приложение, и переназначить все это вашим клиентам.

3 голосов
/ 05 августа 2011

Во многих других языках эквивалент заголовочного файла - это все, что вам нужно.Но обычные компоновщики C в Windows всегда использовали библиотеки импорта, компоновщики C ++ следовали их примеру, и, вероятно, уже слишком поздно их менять.

В качестве мысленного эксперимента можно представить такой синтаксис:

__declspec(dllimport, "kernel32") void __stdcall  Sleep(DWORD dwMilliseconds);

Вооружившись этой информацией, цепочка инструментов компилятора / компоновщика может сделать все остальное.

В качестве дополнительного примера, в Delphi можно импортировать эту функцию, используя неявное связывание, например:

procedure Sleep(dwMilliseconds: DWORD); stdcall; external 'kernel32';

, который показывает, что библиотеки импорта априори не являются необходимыми для связи с DLL.

3 голосов
/ 05 августа 2011

Это так называемая «библиотека импорта», которая содержит минимальную разводку, которая позже (во время загрузки) попросит операционную систему загрузить DLL.

2 голосов
/ 05 августа 2011

DLL это Windows (MS / Intel).(Генерируемая) библиотека содержит код, необходимый для вызова в DLL, и предоставляет «обычные» функции остальной части вашего приложения.

1 голос
/ 05 августа 2011

из 1000 футов, библиотека содержит список функций, которые экспортирует dll, и адреса, необходимые для вызова.

1 голос
/ 05 августа 2011

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

Они используются компилятором для предоставления ему минимальной информации, необходимой для компиляции вашего кода. Он не будет содержать детали реализации.

Однако вам по-прежнему нужно связать все функции и определения переменных, о которых вы сообщили компилятору. Невыполнение этого требования приведет к ошибке компоновщика. Часто это содержится в других объектных файлах, которые могут быть объединены в одну статическую библиотеку.

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

В Unix файлы dll и lib объединены в один файл .so, с которым необходимо связать информацию об ошибках компоновщика.

Вы по-прежнему можете использовать dll без файла .lib, но затем вам придется загрузить и связать все символы вручную с помощью API операционной системы.

1 голос
/ 05 августа 2011

Здесь есть два соответствующих этапа в процессе строительства:

  • компиляция: из исходного кода в объектный файл. Во время компиляции компилятор должен знать, какие внешние объекты доступны, для этого нужно объявление. Объявления, предназначенные для использования в нескольких модулях компиляции, сгруппированы в заголовке. Таким образом, вам нужны заголовки для библиотеки.

  • linking: Для статических библиотек вам нужна скомпилированная версия библиотеки. Для динамических библиотек в Unix вам нужна библиотека, в Windows вам нужна «библиотека импорта».

Можно подумать, что библиотека может также включать объявления или заголовок может включать библиотеку, которая должна быть связана. Первое часто делается на других языках. Второй иногда доступен через прагмы в C и C ++, но стандартного способа сделать это не существует, и он будет конфликтовать с обычным использованием (например, выбор библиотеки из нескольких, которые предоставляют вариант кода для тех же объявлений, например, debug / освободить одну нить / многопоточность). И ни один из этих вариантов не соответствует хорошей модели компиляции C и C ++, которая берет свое начало в 60-х годах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...