Связывание: .a, .lib и .def файлов - PullRequest
27 голосов
/ 21 июня 2011

Я собираю dll из сборки под Windows, используя GNU binutils.

Я знаю, что dll может быть загружена либо при загрузке исполняемого файла, либо во время выполнения (с помощью вызова API LoadLibrary).

Для загрузки во время загрузки мне, кажется, нужен только файл dll: файл .a, .lib или .def не требуется. Мне было интересно, что представляют собой эти форматы файлов и для какой цели они служат.

Что я знаю и некоторые конкретные вопросы:

  • .a - это расширение, обычно используемое для статической библиотеки в Unix. Файлы .a создаются с опцией - out-implib в GNU ld. Говорят, что это «библиотека импорта», достаточно справедливая. Тогда возникает вопрос: «Что мне хорошего в библиотеке импорта, если она мне не нужна при компоновке?»

  • .lib - это расширение, используемое для статической библиотеки в Windows, и, согласно википедии, также используется как «библиотека импорта» под Windows, поэтому я сильно подозреваю, что это просто другое имя для вызова binutils. файлы. Правда / ложь?

  • На всех страницах я могу найти точки, в которых .def-файлы содержат экспортированный символ DLL. Разве это не похоже на то, что должна делать «библиотека импорта»?

  • Кроме того, я прочитал здесь , что использование файлов .def является альтернативой ручному указанию экспорта в исходном файле (что я и сделал). Но я также помню, что при чтении (не могу найти обратную ссылку) .def-файл предоставляет индекс ( ordinal ) в экспортируемые символы, обеспечивая более быструю загрузку во время выполнения. Это так?

1 Ответ

50 голосов
/ 26 июня 2011

Статические библиотеки в Linux имеют расширение .a.Статические библиотеки в Windows имеют расширение .lib.Динамические библиотеки в Windows имеют расширение .dll;для того, чтобы связать с DLL, требуется библиотека импорта.Библиотека импорта является статической библиотекой.Он содержит код, необходимый для загрузки DLL.Теперь вы используете GCC (не cl.exe) для компиляции в Windows.GCC имеет другое соглашение о расширении файлов для библиотек импорта, оно «должно называться * .dll.a или * .a», как описано в документе для --out-implib, на который вы ссылались.

Библиотеки импорта (.lib с MSVC или .dll.a с GCC) являются статическими библиотеками: они содержат код для загрузки DLL. У меня был тот же вопрос на днях.

DLL может иметь функции, которые экспортируются, и функции, которые не экспортируются.Библиотека импорта должна знать, какие функции экспортированы, а какие нет.Одним из способов сообщить об этом является файл DEF.

При сборке библиотеки DLL компоновщик использует файл .def для создания файла экспорта (.exp) и библиотеки импорта (.lib)файл.Затем компоновщик использует файл экспорта для создания файла DLL.Исполняемые файлы, которые неявно ссылаются на DLL, ссылаются на библиотеку импорта при сборке.- MSDN: экспорт из DLL с использованием файлов DEF

Также см. MSDN: экспорт функций из DLL по порядку, а не по имени , вместе которыедолжен ответить на ваш последний вопрос по экспорту по индексу или порядковому номеру.

...