Пошаговое руководство. Создание и использование библиотеки DLL (C++)
В этом пошаговом руководстве описывается создание библиотеки динамической компоновки (DLL) для использования с приложением на C++. Библиотеки являются хорошим способом повторного использования кода. Вместо того чтобы каждый раз реализовывать одни и те же подпрограммы в каждом создаваемом приложении, их можно создать единожды и затем ссылаться на них из других приложений. Поместив код в библиотеку DLL, вы сэкономите место в каждом приложении, которое ссылается на этот код, а также сможете обновлять DLL без перекомпиляции всех приложений. Подробнее о библиотеках DLL см. в статье DLL в Visual C++.
В этом пошаговом руководстве рассматриваются следующие задачи:
создание проекта DLL;
добавление класса в DLL;
создание консольного приложения, использующего динамическую компоновку времени загрузки для ссылки на библиотеку DLL;
использование функциональности из класса в приложении;
запуск приложения.
В этом пошаговом руководстве будет создана библиотека DLL, которая может вызываться только из приложений, использующих соглашения о вызове C++. Сведения о создании библиотек DLL для использования с другими языками см. в статье Вызов функций библиотек DLL из приложений Visual Basic.
Обязательные компоненты
Это руководство предполагает знание основ языка C++.
Создание проекта библиотеки динамической компоновки (DLL)
В строке меню выберите Файл, Создать, Проект.
В левой области диалогового она Создать проект разверните Установленные, Шаблоны, Visual C++ и затем выберите Win32.
В центральной области выберите Консольное приложение Win32.
Укажите имя для проекта, например MathFuncsDll, в поле Имя. Укажите имя для решения, например DynamicLibrary, в поле Имя решения. Нажмите кнопку ОК.
На странице Обзор диалогового окна Мастер приложений Win32 нажмите кнопку Далее.
На странице Параметры приложения выберите в поле Тип приложения пункт DLL.
Нажмите кнопку Готово, чтобы создать проект.
Добавление класса в библиотеку динамической компоновки
Чтобы создать файл заголовка для нового класса, в меню Проект выберите пункт Добавить новый элемент. В диалоговом окне Добавить новый элемент в левой области в разделе Visual C++ выберите Код. В центральной области выберите Заголовочный файл (.h). Укажите имя для заголовка файла, например MathFuncsDll.h, и нажмите кнопку Добавить. Отобразится пустой файл заголовка.
Добавьте следующий код в начало файла заголовка:
// MathFuncsDll.h #ifdef MATHFUNCSDLL_EXPORTS #define MATHFUNCSDLL_API __declspec(dllexport) #else #define MATHFUNCSDLL_API __declspec(dllimport) #endif
Добавьте базовый класс с именем MyMathFuncs, выполняющий обычные арифметические операции, такие как сложение, вычитание, умножение и деление. Код должен выглядеть примерно следующим образом:
namespace MathFuncs { // This class is exported from the MathFuncsDll.dll class MyMathFuncs { public: // Returns a + b static MATHFUNCSDLL_API double Add(double a, double b); // Returns a - b static MATHFUNCSDLL_API double Subtract(double a, double b); // Returns a * b static MATHFUNCSDLL_API double Multiply(double a, double b); // Returns a / b // Throws const std::invalid_argument& if b is 0 static MATHFUNCSDLL_API double Divide(double a, double b); }; }
Когда символ MATHFUNCSDLL_EXPORTS определен, символ MATHFUNCSDLL_API установит модификатор __declspec(dllexport) в объявлениях функций-членов в этом коде. Этот модификатор разрешает экспорт функции библиотекой DLL для использования ее другими приложениями. Если символ MATHFUNCSDLL_EXPORTS не определен, например, когда файл заголовка включен приложением, символ MATHFUNCSDLL_API определяет модификатор __declspec(dllimport) в объявлениях функций-членов. Этот модификатор оптимизирует импорт функции в приложении. По умолчанию шаблон нового проекта для библиотеки DLL добавляет символ PROJECTNAME_EXPORTS в список определенных символов для проекта DLL. В этом примере символ MATHFUNCSDLL_EXPORTS определяется при сборке проекта MathFuncsDll. Для получения дополнительной информации см. dllexport, dllimport.
Примечание
Если проект DLL собирается в командной строке, воспользуйтесь параметром компилятора /D, чтобы определить символ MATHFUNCSDLL_EXPORTS.
В проекте MathFuncsDll в обозревателе решений в папке Исходные файлы откройте файл MathFuncsDll.cpp.
Реализуйте функциональность класса MyMathFuncs в исходном файле. Код должен выглядеть примерно следующим образом:
// MathFuncsDll.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" #include "MathFuncsDll.h" #include <stdexcept> using namespace std; namespace MathFuncs { double MyMathFuncs::Add(double a, double b) { return a + b; } double MyMathFuncs::Subtract(double a, double b) { return a - b; } double MyMathFuncs::Multiply(double a, double b) { return a * b; } double MyMathFuncs::Divide(double a, double b) { if (b == 0) { throw invalid_argument("b cannot be zero!"); } return a / b; } }
Скомпилируйте библиотеку динамической компоновки, выбрав Собрать решение в меню Сборка.
Примечание
При использовании выпуска Express, в котором не отображается меню Сборка, в строке меню выберите Сервис, Параметры, Расширенные параметры, чтобы включить это меню, а затем выберите Сборка, Собрать решение.
Примечание
При сборке проекта из командной строки используйте параметр компилятора /LD, указывающий на то, что выходной файл должен являться DLL-файлом.Для получения дополнительной информации см. /MD, /MT, /LD (использование библиотеки времени выполнения).Используйте параметр компилятора /EHsc для включения обработки исключений С++.Для получения дополнительной информации см. Параметр /EH (модель обработки исключений).
Создание приложения, ссылающегося на DLL
Чтобы создать приложение С++, которое будет ссылаться и использовать созданную ранее библиотеку DLL, в меню Файл выберите пункт Создать и затем пункт Проект.
В левой области в категории Visual C++ выберите Win32.
В центральной области выберите Консольное приложение Win32.
Укажите имя проекта, например MyExecRefsDll, в поле Имя. В раскрывающемся списке рядом с полем Решение выберите Добавить в решение. В результате новый проект будет добавлен в решение, содержащее библиотеку DLL. Нажмите кнопку ОК.
На странице Обзор диалогового окна Мастер приложений Win32 нажмите кнопку Далее.
На странице Параметры приложения выберите в поле Тип приложения пункт Консольное приложение.
На странице Параметры приложения в разделе Дополнительные параметры снимите флажок Предкомпилированный заголовок.
Нажмите кнопку Готово, чтобы создать проект.
Использование функциональности из библиотеки классов в приложении
После создания консольного приложения будет создана пустая программа. Имя исходного файла будет совпадать с ранее выбранным именем. В этом примере он имеет имя MyExecRefsDll.cpp.
Для использования в приложении математических процедур, созданных в библиотеке DLL, необходимо сослаться на эту библиотеку. Для этого в обозревателе решений выберите проект MyExecRefsDll, а затем в меню Проект выберите пункт Ссылки. В диалоговом окне Страницы свойств разверните узел Общие свойства, выберите .NET Framework и ссылки и нажмите кнопку Добавить новую ссылку. Дополнительные сведения о диалоговом окне Ссылки см. в разделе Среда и ссылки, общие свойства и диалоговое окно "Страницы свойств: <Имя проекта>".
В диалоговом окне Добавление ссылки перечислены библиотеки, на которые можно создать ссылку. На вкладке Проект перечислены все проекты текущего решения и включенные в них библиотеки, если они есть. Установите флажок рядом с MathFuncsDll на вкладке Проекты, а затем нажмите кнопку ОК.
Для создания ссылки на файлы заголовка DLL необходимо изменить путь к каталогам включения. Для этого в диалоговом окне Окна свойств последовательно разверните узлы Свойства конфигурации и C/C++, а затем выберите Общие. В поле Дополнительные каталоги включаемых файлов укажите путь к месту размещения файла заголовка MathFuncsDll.h. Можно использовать относительный путь, например ..\MathFuncsDll\. Затем нажмите кнопку ОК.
Теперь класс MyMathFuncs можно использовать в приложении. Замените содержимое файла MyExecRefsDll.cpp следующим кодом.
// MyExecRefsDll.cpp // compile with: /EHsc /link MathFuncsDll.lib #include <iostream> #include "MathFuncsDll.h" using namespace std; int main() { double a = 7.4; int b = 99; cout << "a + b = " << MathFuncs::MyMathFuncs::Add(a, b) << endl; cout << "a - b = " << MathFuncs::MyMathFuncs::Subtract(a, b) << endl; cout << "a * b = " << MathFuncs::MyMathFuncs::Multiply(a, b) << endl; cout << "a / b = " << MathFuncs::MyMathFuncs::Divide(a, b) << endl; try { cout << "a / 0 = " << MathFuncs::MyMathFuncs::Divide(a, 0) << endl; } catch (const invalid_argument &e) { cout << "Caught exception: " << e.what() << endl; } return 0; }
Соберите исполняемый файл, выбрав команду Собрать решение в меню Сборка.
Запуск приложения
Убедитесь в том, что проект MyExecRefsDll выбран в качестве проекта по умолчанию. В обозревателе решений выберите MyExecRefsDll и затем в меню Проект выберите Назначить запускаемым проектом.
Чтобы запустить проект, в строке меню выберите Отладка, Запуск без отладки. Результат выполнения должен выглядеть примерно следующим образом:
a + b = 106,4 a - b = -91,6 a * b = 732,6 a / b = 0,0747475 Перехвачено исключение: b не может быть равно нулю!
См. также
Задачи
Интерактивный учебник по Visual C++
Пошаговое руководство. Развертывание программы (C++)
Основные понятия
Вызов функций библиотек DLL из приложений Visual Basic