Обычные библиотеки DLL, статически компонуемые с MFC
Обычная библиотека DLL, статически компонуемая с MFC, — это библиотека DLL, внутри которой используется MFC, а экспортируемые функции этой библиотеки могут вызываться исполняемыми модулями, которые могут использовать или не использовать MFC. Как следует из названия, этот тип библиотек DLL строится с помощью статически компонуемой версии библиотеки MFC. Зачастую функции экспортируются из обычной библиотеки DLL с помощью стандартного интерфейса C. Пример создания, построения и использования обычной библиотеки DLL см. в разделе DLLScreenCap.
Обратите внимание, что термин USRDLL больше не используется в документации Visual C++. Обычная библиотека DLL, статически связанная с MFC, имеет те же характеристики, что и библиотеки прежней версии USRDLL.
Обычная библиотека DLL, статически компонуемая с MFC, имеет следующие возможности:
Клиентский исполняемый модуль может быть создан на любом языке, поддерживающим использование библиотек DLL (C, C++, Pascal, Visual Basic и т. д.); он не обязан быть приложением MFC.
Библиотека DLL может компоноваться с теми же статическими библиотеками MFC, что и приложения. Больше не существует отдельной версии статически компонуемых библиотек, предназначенных специально для библиотек DLL.
До версии MFC 4.0 библиотеки USRDLL обеспечивали тот же тип функциональности, что и обычные библиотеки DLL, статически компонуемые с MFC. Начиная с версии Visual C++ 4.0 термин USRDLL устарел.
Требования, предъявляемые к обычной библиотеке DLL, статически компонуемой с MFC:
В библиотеках DLL этого типа должен создаваться экземпляр класса, производный от CWinApp.
В библиотеках DLL этого типа используется функция DllMain, предоставляемая MFC. Код инициализации DLL необходимо размещать в функции-члене InitInstance, а код завершения — в функции ExitInstance, как и в обычном приложении MFC.
Несмотря на то, что термин USRDLL устарел, по-прежнему необходимо задавать в командной строке компилятора параметр _USRDLL. Это определение указывает, какие объявления должны выбираться из заголовочных файлов MFC.
Стандартные библиотеки DLL, как и приложения MFC, должны содержать класс, производный от CWinApp, и один объект этого класса. Однако объект CWinApp библиотеки DLL не имеет цикла обработки сообщений CWinApp приложения.
Обратите внимание, что механизм CWinApp::Run неприменим к DLL, потому что главный цикл обработки сообщений находится в приложении. Если библиотека DLL открывает немодальные диалоговые окна или имеет собственное главное окно со фреймом, то главный цикл обработки сообщений приложения должен вызвать процедуру, экспортируемую библиотекой DLL, которая, в свою очередь, вызовет функцию-член CWinApp::PreTranslateMessage объекта приложения библиотеки DLL.
Пример такой функции приведен в разделе DLLScreenCap.
Как правило, символы экспортируются из обычной библиотеки DLL с помощью стандартного интерфейса C. Объявление функции, экспортируемой из обычной библиотеки DLL, выглядит примерно так:
extern "C" __declspec(dllexport) MyExportedFunction( );
Вся выделенная библиотекой DLL память должна использоваться только внутри этой DLL. Библиотека DLL не должна передавать или получать из вызывающего исполняемого модуля следующие объекты:
указатели на объекты MFC;
указатели на память, выделенную MFC.
Если необходимо сделать что-либо из вышеперечисленного или передавать объекты классов, производных от классов MFC, между вызывающим исполняемым модулем и библиотекой DLL, то следует построить библиотеку расширения.
Передавать указатели памяти, выделенной библиотеками времени выполнения языка C, между приложением и библиотекой DLL безопасно только в том случае, если выполняется копирование данных. Нельзя удалять или изменять размеры этих указателей, или же использовать их без копирования памяти.
Библиотеку DLL, статически скомпонованную с MFC, нельзя динамически связывать с общими библиотеками DLL MFC. Статически связанная с MFC библиотека является, как и любые другие DLL, динамически связанной с приложением; приложение связывается с ней так же, как и с любой другой DLL.
Именование стандартных статически связываемых библиотек MFC выполняется согласно правилам, описанным в разделе Соглашения об именовании библиотек DLL MFC. Тем не менее начиная с версии MFC 3.0 больше не требуется вручную указывать компоновщику требуемую версию библиотеки MFC. Файлы заголовков MFC автоматически определяют необходимую версию библиотеки MFC на основе таких директив препроцессора, как _DEBUG и _UNICODE. Заголовочные файлы MFC добавляют директивы /DEFAULTLIB, указывающие компоновщику требуемую версию библиотеки MFC.