EXPORTS
Начинает раздел, состоящий из одного или нескольких определений экспорта, в которых указываются имена или порядковые номера экспортируемых функций или данных. Каждое определение должно находиться в отдельной строке.
EXPORTS
definition
Заметки
Первое определение definition может располагаться в одной строке с ключевым словом EXPORTS или в следующей строке. В файле DEF могут содержаться один или несколько операторов EXPORTS.
Синтаксис определения экспорта definition.
entryname[=internalname] [@ordinal [NONAME]] [[PRIVATE] | [DATA]]
entryname — это имя функции или переменной, которую необходимо экспортировать. Оно является обязательным. Если экспортируемое имя отличается от имени в библиотеке DLL, укажите имя экспорта в DLL с помощью параметра internalname. Например, если библиотека DLL экспортирует функцию func1 и вы хотите, чтобы она вызывалась как функция func2, укажите следующее.
EXPORTS
func2=func1
Так как компилятор Visual C++ использует декорирование имен для функций C++, необходимо использовать декорированное имя в качестве параметра entryname или internalname либо определить экспортируемые функции с помощью extern "C" в исходном коде. Компилятор также декорирует функции C, использующие соглашение о вызове __stdcall, префиксом в виде символа подчеркивания (_) и суффиксом, состоящим из символа @ и числа байтов (в десятичном формате) в списке аргументов.
Чтобы найти декорированные имена, созданные компилятором, используйте средство DUMPBIN или параметр компоновщика /MAP. Декорированные имена зависят от компилятора. Если вы экспортируете декорированные имена в файле DEF, сборка исполняемых файлов, связанных с библиотекой DLL, должна осуществляться с помощью той же версии компилятора. Таким образом обеспечивается совпадение декорированных имен в вызывающем объекте с экспортированными именами в файле DEF.
@ordinal позволяет указать, что номер, а не имя функции попадет в таблицу экспорта библиотеки DLL. Многие библиотеки DLL Windows экспортируют порядковые номера для поддержки устаревшего кода. В 16-разрядном коде Windows часто использовались порядковые номера, так как это позволяло уменьшить размер DLL. Мы не рекомендуем экспортировать функции по порядковым номерам, если это не требуется клиентам библиотеки DLL для поддержки устаревшего кода. Файл LIB будет содержать сопоставление между порядковым номером и функцией, что позволит использовать имя функции, как обычно в проектах, использующих DLL.
Дополнительное ключевое слово NONAME позволяет экспортировать только порядковый номер и сократить размер таблицы экспорта в конечной библиотеке DLL. Однако, если вы хотите использовать GetProcAddress в DLL, необходимо знать порядковый номер, поскольку имя будет недействительным.
Дополнительное ключевое слово PRIVATE не допускает присутствия параметра entryname в библиотеке импорта, созданной LINK. Оно не влияет на экспорт в образ, также созданный с помощью LINK.
Дополнительное ключевое слово DATA указывает на то, что экспорт содержит данные, а не код. Например, переменную с именем exported_global, содержащую данные, можно экспортировать так.
EXPORTS
exported_global DATA
Существует четыре способа экспорта определения; здесь они перечислены в порядке предпочтительности:
ключевое слово __declspec(dllexport) в исходном коде;
оператор EXPORTS в файле DEF;
спецификация /EXPORT в команде LINK;
директива comment в исходном коде в форме #pragma comment(linker, "/export:definition").
Все эти методы можно использовать в одной программе. Когда программа LINK создает программу, содержащую экспорты, она также создает библиотеку импорта (если только при построении не используется файл EXP).
Ниже приведен пример раздела EXPORTS.
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllWindowName = WindowName DATA
DllGetClassObject @4 NONAME PRIVATE
DllRegisterServer @7
DllUnregisterServer
Если экспортируется переменная из библиотеки DLL с помощью файла DEF, вам не надо указывать __declspec(dllexport) для переменной. Однако в любом файле, использующем библиотеку DLL, вы должны использовать __declspec(dllimport) для объявления данных.