Как экспортировать классы C++ из DLL
ОГЛАВЛЕНИЕ
Назначение этой статьи – показать несколько методов экспорта классов C++ из модуля DLL. Исходный код демонстрирует разные приемы экспорта воображаемого объекта Xyz.
Введение
Динамически подключаемые библиотеки (DLL) являются составной частью платформы Windows с самого ее начала. DLL позволяют инкапсулировать часть функционала в автономном модуле с точным списком функций C, доступных внешним пользователям. В 1980-е годы, когда Windows DLL были введены, единственным практичным вариантом разговора с широкой аудиторией разработчиков был язык C. Поэтому Windows DLL предоставляли свой функционал в виде функций и данных C. Внутренне DLL может быть реализована на любом языке, но для использования из других языков и сред интерфейс DLL должен вернуться к наименьшему общему знаменателю – языку C.
Использование интерфейса C не означает автоматически, что разработчик должен отказаться от объектно-ориентированного подхода. Даже интерфейс C можно использовать для истинного объектно-ориентированного программирования, хотя это трудоемкое дело. Неудивительно, что второй наиболее используемый язык программирования, а именно C++, стал жертвой искушения DLL. Однако, в отличие от языка C, где двоичный интерфейс между вызывающей программой и вызываемой программой точно определен и общепринят, в C++ нет признанного двоичного интерфейса приложений (ABI). На деле это значит, что двоичный код, генерируемый компилятором C++, несовместим с другими компиляторами C++. Более того, двоичный код одного и того же компилятора C++ может быть несовместим с другими версиями этого компилятора. Все это затрудняет экспорт классов C++ из DLL.
Назначение этой статьи – показать несколько методов экспорта классов C++ из модуля DLL. Исходный код демонстрирует разные приемы экспорта воображаемого объекта Xyz. Объект Xyz очень простой и имеет только один метод: Foo.
Ниже приведена схема объекта Xyz:
Xyz
int Foo(int)
Реализация объекта Xyz находится внутри DLL, распространяемой по широкому диапазону клиентов. Пользователь может получить доступ к функционалу Xyz путем:
• Использования чистого C
• Использования обычного класса C++
• Использования абстрактного интерфейса C++
Исходный код состоит из двух проектов:
• XyzLibrary – проект библиотеки DLL
• XyzExecutable – консольная программа Win32, использующая "XyzLibrary.dll"
Проект XyzLibrary экспортирует свой код посредством следующего удобного макроса:
#if defined(XYZLIBRARY_EXPORT) // внутри DLL
# define XYZAPI __declspec(dllexport)
#else // вне DLL
# define XYZAPI __declspec(dllimport)
#endif // XYZLIBRARY_EXPORT
Имя XYZLIBRARY_EXPORT определено только для проекта XyzLibrary, поэтому макрос XYZAPI расширяется в __declspec(dllexport) для сборки DLL и в __declspec(dllimport) для сборки клиента.