Подтвердить что ты не робот

.def файлы C/С++ DLL

Я не понимаю, как использовать файлы .def с DLL.

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

Итак, как вы используете .defs при связывании с клиентским приложением, заменяют ли они необходимость использовать заголовок или .lib файл?

4b9b3361

Ответ 1

Я понимаю, что файлы .def предоставляют альтернативу синтаксису __declspec (dllexport), с дополнительным преимуществом, позволяющим явно указывать ординалы экспортируемых функций. Это может быть полезно, если вы экспортируете некоторые функции только по порядку, что не раскрывает столько информации о самой функции (например, многие из внутренних функций экспорта DLL для ОС только по порядку).

См. справочную страницу .

Обратите внимание, что имена в файле .def должны совпадать с именами в двоичном формате. Поэтому, если вы используете C или С++ с "extern" C "{...}", имена не будут искажены; в противном случае вы должны использовать правильные искаженные имена для конкретной версии компилятора, используемого для создания DLL. Функция __declspec() делает это автоматически.

Ответ 2

Я считаю использование обоих файлов __declspec (dllexport) и .def вместе полезными при создании переносимых DLL, то есть DLL, которые могут быть вызваны из кода, скомпилированного с другим компилятором или с разными настройками компилятора.

Простое размещение __declspec (dllexport) в объявлениях функций приведет к тому, что эти функции будут "экспортироваться" вашей DLL (по крайней мере, в Windows), чтобы их можно было вызывать из-за пределов библиотеки DLL.

Однако добавление в файл .def сборки, в котором перечислены все экспортированные функции, позволяет вам остановить компиляторы Microsoft (например) от добавления имени экспортируемого значения подчеркивания и трейлинга к имени экспортируемой функции (по крайней мере, когда они объединены с директивой __stdcall, также полезной для переносимости). Например. объявление функции

void foo(int i);

может быть экспортирован как "_foo @4", если вы не будете осторожны в использовании вызовов и использования файла .def.

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

HANDLE dllHandle = LoadLibrary("mydll.dll");
void* fooFcnPtr = GetProcAddress(dllHandle, "foo");

С надлежащей проверкой ошибок, конечно!

Использование файла .def плюс __stdcall, __declspec (dllexport) и extern "C" в ваших объявлениях функций при создании вашей DLL гарантирует, что вышеуказанный клиентский код будет работать для широкого круга компиляторов и параметров компилятора.

Ответ 3

Для тех, кто еще заинтересован... чтобы иметь возможность ссылаться на файл dll и def, вам также нужен файл lib. В окнах это можно сделать из def с помощью инструмента "LIB". Ниже приведен пример способа командной строки для этого.

lib /machine:i386 /def:sqlite3.def

Надеюсь, что это поможет другим.

Ответ 4

Я не очень много работал с DLL, но я понимаю, что для экспортированных функций С++ вы используете "__declspec (dllexport)", а для экспортированных функций C вы должны написать файл .def. Вероятно, потому, что функции С++ поддерживают перегрузку, но функции C этого не делают.

Ответ 5

. Файлы DEF были более распространены в 16-битных окнах, где они обычно были единственным способом указать, какие символы должны быть экспортированы.

Кроме того, они предоставили средства для указания экспорта по порядковым значениям (@1, @2 и т.д.), а не по имени. Этот метод поиска символов использовался, когда производительность была действительно важна, например, в видеодрайверах.

Ответ 6

Я понимаю, что файлы .def на самом деле не указывают, для чего нужно экспортировать все apis. Он просто содержит экспортированный apis и их порядковые номера. Если вы хотите экспортировать определенный api, вам нужно указать __declspec (dllexport) в определении api и __declspec (dllimport) в объявлении.

Преимущество файла def заключается в том, что он помогает вам поддерживать совместимость с предыдущими записями с уже обработанными dll. то есть он поддерживает порядковые номера для apis. Предположим, что вы добавили новый api в dll, тогда компоновщик смотрит на ваш .def файл, который имеет порядковый номер для ne wapi, так что порядковые номера для старой apis не повреждены.

Итак, если код клиента использует последнюю dll, он не нарушает существующий apis.