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

8

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

Спасибо

@ Максим, я этого не знал. С другой стороны, не существует ли единого гигантского общего пространства имен для всех функций в Linux? David Heffernan
Нет, Linux настолько продвинут, что упаковывает .lib и .dll в один файл .so. Делает это вдвое лучше, чем Windows. :-) Bo Persson
Но как компоновщик времени выполнения узнает, с какой версией библиотеки / библиотеки вы хотите связать, если вы не укажете ее? Eugene S
Потому что компоновщики Windows относительно устарели. В Unix / Linux вам нужны только заголовок и .so. Maxim Egorushkin
Есть. Он состоит из всех символов программы с внешней связью. Следовательно, нет необходимости в глупом __declspec (dllimport). Maxim Egorushkin

Ваш Ответ

7   ответов
2

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

Нет,.lib является более общим. Но их содержание обычно очень зависит от платформы. Henk Holterman
Спасибо за ответ. Являются ли .Lib окнами тоже? какое окончание являются кроссплатформенными библиотеками Peretz
1

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

1

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

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

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

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

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

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

4

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

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

void Multiply(int x, int y);

и этот код:

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

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

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

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

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

о да, я забыл об этой части его вопроса ... должен отредактировать ... дотянуться до ... кнопки ... отредактировать ... :) Я изменю это. C Johnson
@C, @David: Я немного запутался с библиотеками импорта. Если вы говорите компоновщику не включать детали реализации импортированного кода, зачем вообще заботиться о реализации. Просто позаботься позже во время выполнения. Я предполагаю, что причина в том, чтобы иметь возможность запустить отладчик или что-то в этом роде. Peretz
Это все верно, но не демонстрирует необходимость импорта библиотеки. David Heffernan
@Peretz Нет причин, по которым вам нужно использовать файл .lib для связи с DLL с неявными ссылками. Это просто соглашение для компоновщиков C в Windows, но нет необходимости делать это таким образом. Это можно легко сделать с помощью #pragma или некоторого такого специфичного для реализации синтаксиса. David Heffernan
3

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

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

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

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

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

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

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

Компилятор C или C ++ не имеет ничего общего с какими-либо библиотеками. Он только переводит исходный код в объектные файлы. Смотрите мой обновленный комментарий выше. Maxim Egorushkin
@ Дэвид: выглядит лучше. Есть только C-линкеры, нет необходимости заново изобретать линкер для каждого нового языка. Maxim Egorushkin
C не комментирует .lib файлы или имена файлов. MSVC с другой стороны ... Flexo♦
Потому что правильные и подробные ответы веселее. Maxim Egorushkin
Вы ошибаетесь, говоря, что «C всегда использовал библиотеки импорта». На самом деле, C не имеет ничего общего с библиотеками, так как они выходят за рамки стандарта C. Это касается линкеров и зависит от платформы. Maxim Egorushkin
1

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

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

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

Когда я связываю свою библиотеку .lib, могу ли я статически включить ее в свой проект, чтобы впоследствии мне не нужно было включать DLL? как я это сделал?. Кроме того, пока я предоставляю проекту необходимые детали, используя файл .lib, могу ли я использовать файл DLL вместо файла lib для предоставления деталей реализации? Спасибо Peretz
Из исходных текстов вы можете либо создать .LIB, который может быть связан статически (и не понадобится во время выполнения), либо .DLL с сопутствующим .LIB (.LIB будет связан, и потребуется .DLL. во время выполнения). AProgrammer
Для статического связывания (чтобы ничего не требовалось во время выполнения) в Linux вам нужен .a, в windows вам нужен .lib. Для динамического связывания (чтобы библиотека требовалась во время выполнения, но ее можно было легко изменить), вам нужен .so в linux и пара .lib / .dll в windows (.lib не тот, который нужен для статического ссылки). Затем вы можете открыть библиотеку во время выполнения (подумайте о плагине), вам просто нужно .so в Linux и .dll в Windows. AProgrammer
Понял, поэтому файл .lib всегда проясняет детали реализации при разработке кода, и тогда я могу решить, является ли это статической или динамической библиотекой. Что будет эквивалентно файлам .lib и .dll в linux? .so файлы эквивалентны обоим? Peretz
.a эквивалентны .lib и .so - .dll. Но нет необходимости в библиотеке импорта, вы передаете .so компоновщику, а он делает все остальное. AProgrammer
3

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

Спасибо за ответ. Не могли бы вы подробнее объяснить минимальную разводку, которая позже попросит ОС загрузить DLL? Я не уверен в этом процессе. Peretz
Я думаю, что ОП знает, что это такое, но удивляется, зачем это вообще нужно. David Heffernan

Похожие вопросы