Определение подходящего способа экспорта
Функции можно экспортировать одним из двух способов: с помощью файла DEF или ключевого слова __declspec(dllexport)
. Чтобы решить, какой способ лучше подходит для библиотеки DLL, учитывайте следующие моменты.
Вы планируете экспортировать больше функций в дальнейшем?
Библиотека DLL используется только приложениями, которые можно перестроить или использовать в приложениях, которые нельзя перестроить (например, приложения, созданные сторонними производителями)?
Преимущества и недостатки использования файлов DEF
Экспорт функций в файл DEF позволяет контролировать порядковый номер экспорта. При добавлении экспортированной функции в библиотеку DLL можно назначить ей больший порядковый номер по сравнению с любой другой экспортированной функцией. При этом приложения, использующие неявное связывание, не должны повторно связываться с библиотекой импорта, содержащей новую функцию. Это очень удобно, если вы разрабатываете библиотеку DLL для использования сразу несколькими приложениями, поскольку вы можете добавить новые функции, а также убедиться, что она будет работать правильно с приложениями, которые уже используют ее. Например, библиотеки DLL MFC создаются с помощью файлов DEF.
Еще одним преимуществом использования файла DEF является то, что для экспорта функции можно использовать атрибут NONAME
. После этого в таблицу EXPORTS библиотеки DLL помещается только порядковый номер. Для библиотек DLL с большим количеством экспортированных функций использование атрибута NONAME
может уменьшить размер файла DLL. Сведения о том, как написать инструкцию определения модуля, см. в разделе Правила для операторов определения модуля. Сведения об экспорте по порядковому номеру см. в разделе Экспорт функций из библиотеки DLL по порядковому номеру, а не по имени.
Недостаток файла DEF заключается в том, что при экспорте функций в файл C++ необходимо либо поместить в файл DEF внутренние имена, либо определить экспортированные функции с помощью ключевого слова "C", чтобы избежать декорирования имен, выполненных компилятором MSVC.
Если добавить внутренние имена в файл DEF, их можно получить с помощью средства DUMPBIN или с помощью параметра /MAP компоновщика. Внутренние имена, создаваемые компилятором, зависят от компилятора; поэтому при помещении внутренних имен, созданных компилятором, в файл DEF приложения, которые связываются с библиотекой DLL, также должны быть построены с помощью той же версии компилятора, чтобы внутренние имена в вызывающем приложении соответствовали экспортированным именам в файле DEF библиотеки DLL.
Преимущества и недостатки использования __declspec(dllexport)
Использование __declspec(dllexport)
является удобным, поскольку не нужно беспокоиться о поддержке файла DEF и получении внутренних имен экспортируемых функций. Однако полезность такого способа экспорта ограничена числом связанных приложений, которые нужно перестроить. При перестроении библиотеки DLL с новыми данными экспорта необходимо также перестроить приложения, поскольку внутренние имена для C++ экспортированных функций могут измениться, если для их перестроения используется другая версия компилятора.