Разработка DLL (курсовая работа) (545376), страница 7
Текст из файла (страница 7)
Этому вопросу посвящен следующий раздел.dll и mfcПрограммист не обязан использовать mfc при создании динамических библиотек. Однако использованиеmfc открывает ряд очень важных возможностей.Имеется два уровня использования структуры mfc в dll. Первый из них - это обычная динамическаябиблиотека на основе mfc, mfc dll (regular mfc dll). Она может использовать mfc, но не может передаватьуказатели на объекты mfc между dll и приложениями. Второй уровень реализован в динамическихрасширениях mfc (mfc extensions dll). Использование этого вида динамических библиотек требуетнекоторых дополнительных усилий по настройке, но позволяет свободно обмениваться указателями наобъекты mfc между dll и приложением.Обычные mfc dll.Обычные mfc dll позволяют применять mfc в динамических библиотеках.
При этом приложения,обращающиеся к таким библиотекам, не обязательно должны быть построены на основе mfc. В обычныхdll можно использовать mfc любым способом, в том числе создавая в dll новые классы на базе классов mfcи экспортируя их в приложения.Однако обычные dll не могут обмениваться с приложениями указателями на классы, производные от mfc.Если приложению необходимо обмениваться с dll указателями на объекты классов mfc или ихпроизводных, нужно использовать расширение dll, описанное в следующем разделе.Архитектура обычных dll рассчитана на использование другими средами программирования, такими какvisual basic и powerbuilder.При создании обычной библиотеки mfc dll с помощью appwizard выбирается новый проект типа mfcappwizard (dll).
В первом диалоговом окне мастера приложений необходимо выбрать один из режимов дляобычных динамических библиотек: "regular dll with mfc statistically linked" или "regular dll using shared mfcdll". Первый предусматривает статическое, а второй - динамическое подключение библиотек mfc.Впоследствии режим подключения mfc к dll можно будет изменить с помощью комбинированного спискана вкладке "general" диалогового окна "project settings".Управление информацией о состоянии mfc.В каждом модуле процесса mfc содержится информация о его состоянии.
Таким образом, информация осостоянии dll отлична от информации о состоянии вызвавшего ее приложения. Поэтому любыеэкспортируемые из библиотеки функции, обращение к которым исходит непосредственно из приложений,должны сообщать mfc, какую информацию состояния использовать. В обычной mfc dll, использующейдинамические библиотеки mfc, перед вызовом любой подпрограммы mfc в начале экспортируемойфункции нужно поместить следующую строку:afx_manage_state(afxgetstaticmodulestate()) ;Данный оператор определяет использование соответствующей информации о состоянии во времявыполнения функции, обратившейся к данной подпрограмме.Динамические расширения mfc.mfc позволяет создавать такие библиотеки dll, которые воспринимаются приложениями не как наборотдельных функций, а как расширения mfc. С помощью данного вида dll можно создавать новые классы,производные от классов mfc, и использовать их в своих приложениях.Чтобы обеспечить возможность свободного обмена указателями на объекты mfc между приложением и dll,нужно создать динамическое расширение mfc.
dll этого типа подключаются к динамическим библиотекамmfc так же, как и любые приложения, использующие динамическое расширение mfc.Чтобы создать новое динамическое расширение mfc, проще всего, воспользовавшись мастеромприложении, присвоить проекту тип mfc appwizard (dll) и на шаге 1 включить режим "mfc extension dll". Врезультате новому проекту будут присвоены все необходимые атрибуты динамического расширения mfc.Кроме того, будет создана функция dllmain для dll, выполняющая ряд специфических операций поинициализации расширения dll.
Следует обратить внимание, что динамические библиотеки данного типане содержат и не должны содержать объектов, производных от cwinapp.Инициализация динамических расширенийЧтобы "вписаться" в структуру mfc, динамические расширения mfc требуют дополнительной начальнойнастройки. Соответствующие операции выполняются функцией dllmain. Рассмотрим пример этой функции,созданный мастером appwizard.static afx_extension_module myextdll = { null, null } ;extern "c" int apientrydllmain(hinstance hinstance, dword dwreason, lpvoid ipreserved){if (dwreason == dll_process_attach){traced("myext.dll initializing!n") ;// extension dll one-time initializationafxinitextensionmodule(myextdll, hinstance) ;// insert this dll into the resource chainnew cdynlinklibrary(myextdll);}else if (dwreason == dll_process_detach){traced("myext.dll terminating!n") ;}return 1; // ok}Самой важной частью этой функции является вызов afxinitextensionmodule.
Это инициализациядинамической библиотеки, позволяющая ей корректно работать в составе структуры mfc. Аргументамиданной функции являются передаваемый в dllmain дескриптор библиотеки dll и структураafx_extension_module, содержащая информацию о подключаемой к mfc динамической библиотеке.Нет необходимости инициализировать структуру afx_extension_module явно. Однако объявить ее нужнообязательно. Инициализацией же займется конструктор cdynlinklibrary. В dll необходимо создать классcdynlinklibrary. Его конструктор не только будет инициализировать структуру afx_extension_module, но идобавит новую библиотеку в список dll, с которыми может работать mfc.Загрузка динамических расширений mfc.Начиная с версии 4.0 mfc позволяет динамически загружать и выгружать dll, в том числе и расширения.Для корректного выполнения этих операций над создаваемой dll в ее функцию dllmain в моментотключения от процесса необходимо добавить вызов afxtermextensionmodule.
Последней функции вкачестве параметра передается уже использовавшаяся выше структура afx_extension_module. Для этого втекст dllmain нужно добавить следующие строки.if(dwreason == dll_process_detach){afxtermextensionmodule(myextdll);}Кроме того, следует помнить, что новая библиотека dll является динамическим расширением и должназагружаться и выгружаться динамически, с помощью функций afxloadlibrary и afxfreelibrary,а неloadlibrary и freelibrary.Экспортирование функций из динамических расширенийРассмотрим теперь, как осуществляется экспортирование в приложение функций и классов издинамического расширения. Хотя добавить в def-файл все расширенные имена можно и вручную, лучшеиспользовать модификаторы для объявлений экспортируемых классов и функций, такие как afx_ext_classи afx_ext_api,например:class afx_ext_class cmyclass : public cobject(// your class declaration}void afx_ext_api myfunc() ;.