Разработка dll модулей расширения mfc на языке visual c


Содержание

Visual C++ для начинающих
Страница 31. Динамические расширения MFC

Динамические расширения 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.

Самой важной частью этой функции является вызов 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 нужно добавить следующие строки.

Кроме того, следует помнить, что новая библиотека DLL является динамическим расширением и должна загружаться и выгружаться динамически, с помощью функций AfxLoadLibrary и AfxFreeLibrary,а не LoadLibrary и FreeLibrary.

Экспортирование функций из динамических расширений

Рассмотрим теперь, как осуществляется экспортирование в приложение функций и классов из динамического расширения. Хотя добавить в DEF-файл все расширенные имена можно и вручную, лучше использовать модификаторы для объявлений экспортируемых классов и функций, такие как AFX_EXT_CLASS и AFX_EXT_API,например:

Разработка DLL на языке С++

Страницы работы

Содержание работы

Как создать DLL

Сначала разработаем DLL на языке С++ и рассмотрим, как вызвать ее из клиентского модуля, написанного на том же языке.

¨ В меню File4New выберите команду Project.

¨ В появившемся окне диалога New Project, в окне Project Type раскройте узел дерева под именем Visual C++ Projects4Win32. В окне Templates выберите шаблон — Win32 Projects.

¨ В окне Name задайте имя решения MyDLL.

¨ В окне Location задайте местоположение новой папки с файлами решения (solution) и нажмите OK.

¨ В окне мастера Win32 Application Wizard выберите страницу Application Settings.

¨ Установите два флага: DLL, Exports symbols и нажмите Finish.

¨ Откройте окно свойств проекта и откажитесь от Unicode (установите Use Multibyte characters).

Так как проект достаточно прост (а также потому, что я считаю полезным рассматривать крайние варианты) удалите из проекта и уничтожьте файл MyDLL.h. В файл MyDLL.cpp мы внесем достаточно много изменений. Их суть такова. Обычно DLL экспортирует функции, которые надо специальным образом пометить. Но Microsoft Visual Studio предоставляет расширенные возможности. Вы можете экспортировать не только глобальные функции, но и переменные произвольных типов, и даже классы.

В Visual Studio существует три разных способа объявления экспортируемых функций. Рассмотрим самый прогрессивный из них. Он использует директивы и описатели, которые являются Microsoft-расширением языка С++. Все экпортируемые сущности должны иметь описатель __declspec(dllexport). В клиентском приложении эти же функции должны иметь описатель: __declspec(dllimport). При этом способе не нужен DEF-файл, который используется в ином (традиционном) подходе.

Илон Маск рекомендует:  Что такое код do while

Мы будем экспортировать 2 переменные (progress, error), 4 функции (Gauss, Solve, AllocMatrix и ClearMatrix) и один класс (Geometry). Переменные и класс имеют одну цель — проиллюстрировать возможности экспорта DLL, три из четырех функций носят более утилитарный характер. Думаю, что они могут оказаться действительно полезными для вас. Класс Geometry и функция Solve тоже могут стать полезными, если вы вместо пустой заготовки функции Solve вставите коды алгоритма матричной прогонки (см. книгу: Самарский А.А. Методы решения сеточных уравнений).

Здесь же мы ставим более простую цель — написать программу решения системы линейных алгебраических уравнений произвольного порядка n методом исключения неизвестных (Гаусса). Значение размерности системы будет известно только во время выполнения клиентской программы, когда пользователь введет желаемый порядок. С учетом сказанного, внесите в файл MyDLL.cpp следующие изменения.


#include «stdafx.h» // Сокращает время повторных компиляций

__declspec(dllexport) int progress = 0;

__declspec(dllexport) char* error = «No error»;

__declspec(dllexport) void AllocMatrix (double**& a, int ny, int nx)

a = new double* [ny];

for (int i=0; i = 0; —k) // Backward substitution

Разработка dll модулей расширения mfc на языке visual c

55 просмотра

1 ответ

6 Репутация автора

Я построил следующую конфигурацию:

1) Расширение MFC dll с диалогом A (класс MultipleTextBox)

2) Приложение MFC имеет диалоговое окно B. (диалоговое окно A как дочерний элемент диалогового окна B)

диалог B объявляет экземпляр диалога A в заголовочном файле:

в диалоге B функция OnInitDialog:

Но диалоговое окно A не отображается при запуске приложения.

Ответы (1)

плюса

1201 Репутация автора

Это вероятно из-за пропущенного вызова

дайте вызов вышеупомянутой функции, и тогда диалог появится в вашем приложении.

Разработка приложений на Visual C++ MFC

Открыв проект, созданный при помощи «Мастера приложений», то Вы увидите пустое окно (возможно это исправили в версиях позднее Visual C++ 2010). Для того, чтобы вернуть диалоговое окно, которые было у нас в прошлом уроке, следует активировать вкладку «Окно ресурсов», открыть папку «Dialog», и в ней два раза щелкнуть по «IDD_имя_проекта».

Если Вы не найдете вкладки «Окно ресурсов», то следует сделать ее видимой, для этого: «Вид»>>«Ресурсы». Еще необходимо активировать «Обозреватель решений», чтобы было возможно в ходе работы переключаться между диалоговым окном и кодом программы. Теперь, когда все готово, напишем программу, имеющую практическое значение.

Постановка задачи:

Написать программу, пересчета из градусов в радианы. Пользователь должен вводить значения в градусах, а получать эти же значения в радианах. Визуально это будет выглядеть так: в центре окна располагается фрейм для ввода данных, под ним кнопка «Выход» и кнопка «Пересчитать».

Решение задачи:

Для начала удалим метку TODO из нашей программы (выделить и нажать Delete). При помощи «Панели элементов» добавим метку (Static Text) и поле редактирования (Edit Control).

Изменим текст метки, для этого выделим ее и нажав правую клавишу мыши выберем пункт «Свойства». Справа появится панель, в строке «Подпись» изменим значение «Статический» на «Введите значение в градусах».


Аналогичным образом изменим значение «Подпись» (Caption англ.) у кнопок «ОК» и «Отмена», на «Пересчитать» и «Выход». Окно вашей программы должно быть примерно, такое как на скриншоте.

Теперь напишем функцию, которая будет определять действие программы после нажатия пользователя по кнопке «Пересчитать». Для переопределения действий необходимо:

  1. В свойствах кнопки поменять значение параметра ID, впишем туда значение ID_radian. Значение, которое стоит по умолчанию закрывает диалоговое окно, что нам не нужно.
  2. Щелкаем дважды по кнопке «Пересчитать» и попадаем в окно с кодом, где в качестве тела функции OnBnClickedradian() вводим строку MessageBox(«Пока нет текста функции обработки»);. Запустив приложение и нажав на кнопку «Пересчитать», Вы должны увидеть следующие окно, иначе (скорее всего) допущена ошибка в настройках при создании проекта.
  3. Осталось написать текст в функцию OnBnClickedradian, но сначала добавим переменную, которая будет отвечать за «Поле редактирования». Для этого щелкаем правой кнопкой мыши по полю в которое вводятся данные, выбираем «Добавить переменную…». Появится окно, в поле «Имя переменной» вписываем название этой самой переменной (я написал m_Edit). В ее свойствах указываем тип возвращаемого компонентом значения (выберем float), для этого: «Категория»->«Тип переменной»->float. Должно быть так как на скриншоте

Запускаем наше приложение, надеясь что оно работает). Результат выглядит примерно так

Подводя итоги, выделим основные этапы создания простого визуального приложения:

  1. Создаем шаблон приложения типа «Диалоговое окно»;
  2. Размещаем в этом окне нужные нам компоненты при помощи «Панели элементов»;
  3. Изменяем >

Exporting a MFC Dialog from a DLL

21st July: Updated, see bottom

In VC++ 2005 I have 2 projects. Firstly, a MFC DLL project (not an extension DLL) which has a simple dialog:

TestDlg.h

Then I have a Win32 console app, with MFC libraries, that does:

TestApp.cpp

It builds and runs up, but no dialog appears. Stepping into DoModal().

dlgcore.cpp

For whatever reason it seems it can’t load the resource, returning -1 at the end of the copied section. I’ve looked at a few articles on CodeGuru, etc, and not seen anything obvious. Is my class not being exported/imported right? Or is it a resource problem? Or is the problem that I’m trying to display it from a console (MFC) app?

21st July Update I created an overridden DoModal as so:

This seems to work although should I be overriding a different method to get the functionality more generic?

4 Answers 4

As you’ve noted, the problem is that MFC is not finding the resource, since the module context is set to your main EXE rather than the DLL containing the dialog resource.

Manually calling AFX_MANAGE_STATE to ensure the DLL context is established is one way to work this, but it’s not transparent. The ideal way is to compile your DLL as an extension DLL, so that MFC can take care of loading the resource from a list of extension DLLs and managing memory between the DLLs.

You may be able to short-cut creating the extension DLL and simply create your own CDynLinkLibrary instance, which adds your DLL to the main resource list. I have not tried this, preferring instead to take the extension dll _AFXDLL route, so this may or may not work.

The MSDN article on Extension DLLs may help you determine if they are suitable in your case, and what advantages/drawbacks they bring.

Разработка dll модулей расширения mfc на языке visual c

Самая актуальная документация по Visual Studio 2020: Документация по Visual Studio 2020.

Библиотека динамической компоновки (DLL) является исполняемым файлом, который выступает в качестве общей библиотеки функций и ресурсов. Динамическая компоновка позволяет исполняемому файлу вызывать функции или использовать ресурсы, хранящиеся в отдельном файле. Эти функции и ресурсы можно компилировать и развертывать отдельно от использующих их исполняемых файлов. Операционная система может загрузить библиотеку DLL в область памяти исполняемого файла во время загрузки этого исполняемого файла или по запросу во время выполнения. Библиотеки DLL также упрощают совместное использование функций и ресурсов различными исполняемыми файлами. Несколько приложений могут осуществлять одновременный доступ к содержимому одной копии библиотеки DLL в памяти.

Статическая компоновка копирует весь код объектов из LIB-файла в исполняемый файл. Динамическая компоновка включает только те сведения, которые позволяют найти и загрузить библиотеку DLL, содержащую элемент данных или функцию, во время выполнения. При создании библиотеки DLL можно также создать LIB-файл, содержащий эту информацию. При сборке исполняемого файла, который вызывает библиотеку DLL, компоновщик использует экспортированные символы в LIB-файле, чтобы сохранить эти сведения для загрузчика. Когда загрузчик загружает библиотеку DLL, она сопоставляется с областью памяти исполняемого файла. Вызывается специальная функция в библиотеке DLL — DllMain — для выполнения любой необходимой библиотеке DLL инициализации.

Динамическая компоновка имеет некоторые преимущества над статической. При использовании библиотек DLL можно сохранить область памяти и уменьшить объем переключений. Если несколько приложений могут использовать одну копию библиотеки DLL, можно сэкономить место на диске и пропускную способность для скачивания. Библиотеки DLL можно развертывать и обновлять по отдельности, что позволяет предоставлять послепродажную поддержку и обновления программного обеспечения без необходимости перестроения и отправки всего кода. Библиотеки DLL — удобный способ для предоставления ресурсов под определенный языковой стандарт, которые могут поддерживать многоязычные программы и упрощают создание международных версий приложений.

В следующих разделах представлена подробная информация о программировании библиотек DLL.

Пошаговое руководство. Создание и использование библиотеки DLL (C++)
Описывает создание и использование библиотек DLL при помощи Visual Studio.


Типы библиотек DLL
Предоставляет сведения о различных типах библиотек DLL, которые доступны для сборки.

Вопросы и ответы по библиотекам DLL
Ответы на часто задаваемые вопросы о библиотеках DLL.

Связывание исполняемого файла с библиотекой DLL
Описание явного и неявного соединения с библиотекой DLL.

Инициализация библиотеки DLL
Процесс инициализации кода (такой как распределение памяти) в DLL, необходимый для выполнения загрузки библиотеки DLL.

Поведение библиотеки времени выполнения
Выполнение библиотекой времени выполнения функции запускаемой последовательности DLL.

Функции LoadLibrary и AfxLoadLibrary
Использование функций LoadLibrary и AfxLoadLibrary для явной связи с библиотекой DLL во время выполнения.

Функция GetProcAddress
Использование GetProcAddress для получения адреса экспортированной функции в DLL.

Функции FreeLibrary и AfxFreeLibrary
Использование FreeLibrary и AfxFreeLibrary , без необходимости применения модуля DLL.

Путь поиска, используемый Windows для размещения библиотеки DLL
Описание пути поиска, который операционная система Windows использует для поиска библиотеки DLL в системе.

Состояние модулей регулярной динамической библиотеки DLL, связанной с MFC
Состояние модулей регулярной динамической библиотеки DLL, связанной с MFC.

Библиотеки DLL расширения
Наличие библиотек DLL, которые обычно реализуют классы многократного использования в существующих библиотеках классов Microsoft Foundation Class.

Создание библиотек DLL, содержащих только ресурсы
Библиотека DLL, содержащая только ресурсы, например значки, растровые изображения, строки и диалоговые окна.

Локализованные ресурсы в приложениях MFC: вспомогательные библиотеки DLL
Расширенная поддержка библиотек спутниковой связи DLL и содержит функцию, которая позволяет создавать приложения, локализированные на различные языки.

Импортирование и экспортирование
Импортирование открытых символов в приложение или экспортирование функций из библиотеки DLL

Технология Active и библиотеки DLL
Размещение серверов объектов внутри библиотеки DLL.

Автоматизация в библиотеке DLL
Параметр автоматизации в решениях мастера библиотек DLL MFC.

Соглашения об именовании библиотек DLL MFC
Способ встраивания библиотек DLL в MFC, опираясь на четко структурированное соглашение об именовании.

Использование MFC как часть библиотеки DLL
Постоянные библиотеки DLL, которые позволяют использовать MFC-библиотеку как часть библиотеки динамической компоновки Windows.

Версия библиотеки DLL MFC
Механизм использования библиотек динамической компоновки MFCxx.dll и MFCxxD.dll (где x является номером версии MFC) с приложениями MFC и расширениями библиотек DLL.

(NOTINBUILD)Visual C++ Programming Methodologies
Ссылки на разделы, содержащие теоретические сведения о библиотеках Visual C++, а также описание различных технологий и методик программирования.

Создать MFC DLL из C/C++ (VS 2010) код, который будет использоваться веб-службой C# WCF

У меня есть сторонний компонент, написанный на C/C++ (на VS 2010), который можно загрузить here.

Этот компонент принимает 3 параметра в качестве входных данных (имя файла и два номера) и выводит результат на консоль, а затем выводит файл.

Я использовал Process и ProcessStartInfo в проекте C# WinForm, чтобы использовать этот компонент, который отлично работает. Однако теперь я хочу использовать это в службе WCF C# RESTful, и в этом случае решение, которое я думал с WinForm, не будет работать. Было предложено вместо этого преобразовать это в MFC DLL, а затем использовать InterOp для вызова неуправляемой DLL через мой веб-сервис C# (другие предложения приветствуются).

К сожалению, я понятия не имею, как это сделать, и мои знания о C/C++ довольно обычны. Так что мой вопрос: Как создать DLL из этого компонента, который принимает эти 3 параметра (из основных()):

затем делает все, что расчеты он должен делать, и вернуть это (опять же берется из основных()):

(и, очевидно, все еще выдавать файл, который предполагается вывести)?

Любая помощь была бы высоко оценена. Спасибо заранее!

ОБНОВЛЕНИЕ: В качестве отправной точки здесь приведена моя реализация WinForm, упомянутая выше.


Создан 24 мар. 12 2012-03-24 05:00:33 globetrotter

Разработка dll модулей расширения mfc на языке visual c

55 просмотра

1 ответ

6 Репутация автора

Я построил следующую конфигурацию:

1) Расширение MFC dll с диалогом A (класс MultipleTextBox)

2) Приложение MFC имеет диалоговое окно B. (диалоговое окно A как дочерний элемент диалогового окна B)

диалог B объявляет экземпляр диалога A в заголовочном файле:

в диалоге B функция OnInitDialog:

Но диалоговое окно A не отображается при запуске приложения.

Ответы (1)

плюса

1201 Репутация автора

Это вероятно из-за пропущенного вызова

дайте вызов вышеупомянутой функции, и тогда диалог появится в вашем приложении.

Создать MFC DLL из C/C++ (VS 2010) код, который будет использоваться веб-службой C# WCF

У меня есть сторонний компонент, написанный на C/C++ (на VS 2010), который можно загрузить here.

Этот компонент принимает 3 параметра в качестве входных данных (имя файла и два номера) и выводит результат на консоль, а затем выводит файл.

Я использовал Process и ProcessStartInfo в проекте C# WinForm, чтобы использовать этот компонент, который отлично работает. Однако теперь я хочу использовать это в службе WCF C# RESTful, и в этом случае решение, которое я думал с WinForm, не будет работать. Было предложено вместо этого преобразовать это в MFC DLL, а затем использовать InterOp для вызова неуправляемой DLL через мой веб-сервис C# (другие предложения приветствуются).

К сожалению, я понятия не имею, как это сделать, и мои знания о C/C++ довольно обычны. Так что мой вопрос: Как создать DLL из этого компонента, который принимает эти 3 параметра (из основных()):

затем делает все, что расчеты он должен делать, и вернуть это (опять же берется из основных()):

(и, очевидно, все еще выдавать файл, который предполагается вывести)?

Любая помощь была бы высоко оценена. Спасибо заранее!

ОБНОВЛЕНИЕ: В качестве отправной точки здесь приведена моя реализация WinForm, упомянутая выше.

Создан 24 мар. 12 2012-03-24 05:00:33 globetrotter

Основы программирования на языке Си++. Часть IV. Программирование для Microsoft Windows с использованием Visual C++ и библиотеки классов MFC

Для того, чтобы оценить ресурс, необходимо авторизоваться.

Пособие предназначено для обучения студентов, обладающих навыками пользовательской работы на персональном компьютере, основным понятиям и методам современного практического программирования. Предметом изучения курса является объектно-ориентированное программирование на языке Си++ в среде современных 32-х разрядных операционных систем семейства Windows. Программа курса разбита на 4 части: (1) Введение в программирование на языке Си++; (2) Основы программирования трехмерной графики; (3) Объектно-ориентированное программирование на языке Си++ и (4) Программирование для Microsoft Windows с использованием Visual C++ и библиотеки классов MFC. После изучения курса студент получает достаточно полное представление о содержании современного объектно-ориентированного программирования, об устройстве современных операционных систем Win32 и о событийно-управляемом программировании. На практических занятиях вырабатываются навыки программирования на Си++ в интегрированной среде разработки Microsoft Visual C++ 5.0.

Илон Маск рекомендует:  Адаптивный макет на флексбоксах
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL