Атрибут __dеclspec(dllexport)
должен указываться в начале объявления экспортируемой функции или данных, вслед за какими-либо спецификаторами сборки, и сразу за ним должно следовать ключевое слово class
или struct
для экспортируемого класса. Это проиллюстрировано в примере 1.6. Заметьте, что __declspec(dllexport)
не является частью языка С++; это расширение языка, реализованное для большинства компиляторов для Windows.
• Создание файла
__declspec(dllexport) int m = 3; // Экспортируемое определение данных
extern __declspec(dllexport) int n; // Экспортируемое объявление данных
__declspec(dllexport) void f(); // Экспортируемое объявление функции class
__declspec(dllexport) c { // Экспортируемое определение класса
/* ... */
};
Использование файла __declspec(dllexport)
. Чтобы изучить полный синтаксис файлов
Как есть два способа экспорта символов из DLL, так есть и два способа импорта символов.
• В заголовочных файлах, включенных в исходный код, использующий DLL, используйте атрибут __declspec(dllimport)
и при сборке этого кода передайте библиотеку импорта компоновщику.
• При сборке кода, использующего DLL, укажите файл
Как и в случае с экспортом символов, я рекомендую вместо файлов __declspec(dllimport)
. Атрибут __declspec(dllimport)
используется точно так же, как и атрибут __declspec(dllexport)
, обсуждавшийся ранее. Аналогично __declspec(dllexport)
атрибут __declspec(dllimport)
не является частью языка С++, а является расширением языка, реализованным для большинства компиляторов для Windows.
Если вы выбрали использование __declspec(dllexport)
и __declspec(dllimport)
, вы должны убедиться, что при сборке DLL использовали __declspec(dllexport)
, а при компиляции кода, использующего эту DLL, использовали __declspec(dllimport)
. Одним из подходов является использование двух наборов заголовочных файлов: одного для сборки DLL, а другого для компиляции кода, использующего эту DLL. Однако это неудобно, так как сложно одновременно сопровождать две отдельные версии одних и тех же заголовочных файлов.
Вместо этого обычно используют определение макроса, который при сборке DLL расширяется как __declspec(dllexport)
, а в противном случае — как __declspec(dllimport)
. В примере 1.2 я использовал для этой цели макроопределение GEORGERINGO_DECL
. В Windows, если определен символ GEORGERINGO_SOURCE
, то GEORGERINGO_DECL
раскрывается как __declspec(dllexport)
, а в противном случае — как __declspec(dllimport)
. Описанный результат вы получите, определив GEORGERINGO_SOURCE
при сборке DLL