Ссылка на DLL с файлом DEF вместо файла LIB? - PullRequest
3 голосов
/ 17 июля 2011

Я узнал, что вы можете:

  • Преобразовать файл .DLL в файл .DEF , который включает его экспорт
    (Изменить: Это не работает со многими соглашениями)
  • Преобразуйте файл .DEF в файл .LIB, который вы можете использовать для ссылки на DLL

Почему (большинство) компоновщиков не могут ссылаться на DLL, заданную только файлом .DEF вместо файла .LIB?

Ответы [ 4 ]

4 голосов
/ 17 июля 2011

В конечном счете, ответ здесь таков: «потому что никто не хотел этого достаточно сильно, и это на самом деле ничего не помогает».

Файл DEF является входным файлом, который создает lib для импорта библиотеки DLL.И потом, позже, когда DLL используется другой ссылкой, importlib сам по себе является вводом.Importlib выглядит как нечто особенное снаружи, но когда вы смотрите внутрь, на самом деле это просто немного особенная библиотека с объектами внутри.

Было бы вполне возможно изменить компоновщик так, чтобы он принимал файл def (или DLL, в этом отношении) напрямую.

Но центр компоновщика состоит в том, что он принимает объекты в качестве входных данных и выводит исполняемый файл PE.Таким образом, использование DEF или DLL в качестве входных данных выходит за рамки шаблона проектирования.

Кроме того, это было бы довольно бессмысленно - разрешение компоновщику принимать файл DEF или DLL в качестве входных данных не будет включать любые важные новые сценарии,и не оставляя эту функцию, ничего не блокирует.Преобразование имеющегося у вас файла DEF (даже без фактической DLL) в пригодную для использования importlib - это работа нескольких минут (просто создайте поддельную пустую функцию для каждой записи DEF и свяжите ее).Поэтому нет причин добавлять возможность напрямую связывать файл DEF.

Martyn

2 голосов
/ 18 июля 2011

В терминах MSVC файлы .lib всегда являются статическими библиотеками. Они связаны как единица компиляции вместе со всеми вашими скомпилированными файлами .c / .cpp, поэтому весь код библиотеки включен в ваш окончательный исполняемый файл.

Однако некоторые .lib-файлы (в частности, большинство системных файлов Windows) просто содержат заглушки, которые сообщают ОС, что нужно загрузить желаемую DLL во время загрузки, а затем вызывают вызовы функции маршрутизации заглушек в DLL. Но эти заглушки статически связаны с вашим исполняемым файлом. Затем ваша программа будет использовать библиотеки DLL (и получит все их преимущества и недостатки), но поскольку требуемые ей именованные функции DLL удачно расположены в .lib (и, таким образом, фактически находятся в самом исполняемом файле), ваш код не должен знаю, что он использует DLL (в частности, использует declspec (dllimport)).

Файл .def просто используется как своего рода «файл настроек» или «файл конфигурации» во время создания .dll, чтобы указать, какие функции должен экспортировать файл. С ним нельзя связываться, так как он не описывает ничего, что понимает компоновщик.

2 голосов
/ 17 июля 2011

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

Из документов :

Файл DLL имеет макет, очень похожий на файл .exe, с одним Важное отличие - файл DLL содержит таблицу экспорта. Таблица экспорта содержит имя каждой функции, которую экспортирует DLL другим исполняемым файлам. Эти функции являются точками входа в DLL; только функции в таблице экспорта могут быть доступны другим исполняемые файлы. Любые другие функции в DLL являются частными для DLL. Таблицу экспорта DLL можно просмотреть с помощью инструмента DUMPBIN. с параметром / EXPORTS.

Вы можете экспортировать функции из DLL двумя способами:

Создайте файл определения модуля (.def) и используйте файл .def, когда сборка DLL. Используйте этот подход, если вы хотите экспортировать функции из вашей DLL по порядковому номеру, а не по имени.

Используйте ключевое слово __declspec (dllexport) в определении функции.

При экспорте функций любым методом обязательно используйте __stdcall соглашение о вызовах.

Используйте предоставленную ссылку, чтобы узнать больше об экспорте из ваших DLL.

Я думаю, что вы проголосовали, потому что ваша точка зрения не совсем ясна, по крайней мере, мне. Также проверьте это . Объясняется, как выбрать метод экспорта.

1 голос
/ 17 июля 2011

Mehrdad, это не всегда вопрос о том, как СВЯЗАТЬСЯ с DLL, так как лично я НИКОГДА не связывал DLL с помощью файла .DEF.Что я сделал , так это взял чужую DLL и очень тщательно создал файл заголовка, или, скорее, прототипы функций, которые я мог бы использовать с LoadLibrary() в C, Declare Function ... Lib "Foo.dll" Alias "OrdinalName" в VB и [DllImport()]в C #.

Конечно, это РЕАЛЬНО сделано, как будто вы используете DLL для чего-то, обычно у вас есть разрешение на это, и авторы предоставляют .lib и заголовки, чтобы идти сбинарный файл DLL.

Я никогда не использовал точные методы, о которых вы говорите, путем преобразования информации .DEF в .LIB и т. д. Но, я полагаю, было бы легко взять библиотеку, илисама DLL и экспорт .DEF из нее.Теперь, что я на самом деле БЫЛ сделал в проекте, где код DLL был построен с использованием vbScript, который взял код из основного проекта и создал API из всего существующего, скомпилированного и протестированного кода.Этот уровень сложности был сделан только потому, что я понятия не имел, какие функции будут в BE, поскольку основной проект может измениться в любое время, поэтому статический файл .DEF никогда бы не сработал.Итак, мне пришлось собрать DLL один раз, перехватить dimpbin /exports, декорировать функции, а затем собрать файл .DEF и заново связать DLL.

Если вы оказались в ситуации такого типа, возможно, вам нужно переосмыслить ваш оригинальный дизайн и устранить проблему оттуда ...

Что касается файлов .LIB, обычно вы бы NEED только для статических связей,но они также используются, когда файл .H доступен, часто делая отладку немного более приятной ...

...