Рекомендуем использовать Visual Studio 2017

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

 

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

В этом пошаговом руководстве описывается создание библиотеки динамической компоновки (DLL) для использования с приложением на C++. Библиотеки являются хорошим способом повторного использования кода. Вместо того чтобы каждый раз реализовывать одни и те же подпрограммы в каждом создаваемом приложении, их можно создать единожды и затем ссылаться на них из других приложений. Поместив код в библиотеку DLL, вы сэкономите место в каждом приложении, которое ссылается на этот код, а также сможете обновлять DLL без перекомпиляции всех приложений. Подробнее о библиотеках DLL см. в статье DLL в Visual C++.

В этом пошаговом руководстве рассматриваются следующие задачи:

  • создание проекта DLL;

  • добавление класса в DLL;

  • создание консольного приложения, использующего динамическую компоновку времени загрузки для ссылки на библиотеку DLL;

  • использование функциональности из класса в приложении;

  • запуск приложения.

В этом пошаговом руководстве будет создана библиотека DLL, которая может вызываться только из приложений, использующих соглашения о вызове C++. Сведения о создании библиотек DLL для использования с другими языками см. в статье Вызов функций библиотек DLL из приложений Visual Basic.

Это руководство предполагает знание основ языка C++.

Создание проекта библиотеки динамической компоновки (DLL)

  1. В строке меню выберите Файл, Создать, Проект.

  2. В левой области диалогового она Создать проект разверните Установленные, Шаблоны, Visual C++ и затем выберите Win32.

  3. В центральной области выберите Консольное приложение Win32.

  4. Укажите имя для проекта, например MathFuncsDll, в поле Имя. Укажите имя для решения, например DynamicLibrary, в поле Имя решения. Нажмите кнопку ОК.

  5. На странице Обзор диалогового окна Мастер приложений Win32 нажмите кнопку Далее.

  6. На странице Параметры приложения выберите в поле Тип приложения пункт DLL.

  7. Нажмите кнопку Готово, чтобы создать проект.

Добавление класса в библиотеку динамической компоновки

  1. Чтобы создать файл заголовка для нового класса, в меню Проект выберите пункт Добавить новый элемент. В диалоговом окне Добавить новый элемент в левой области в разделе Visual C++ выберите Код. В центральной области выберите Заголовочный файл (.h). Укажите имя для заголовка файла, например MathFuncsDll.h, и нажмите кнопку Добавить. Отобразится пустой файл заголовка.

  2. Добавьте следующий код в начало файла заголовка:

    // MathFuncsDll.h
    
    #ifdef MATHFUNCSDLL_EXPORTS
    #define MATHFUNCSDLL_API __declspec(dllexport) 
    #else
    #define MATHFUNCSDLL_API __declspec(dllimport) 
    #endif
    
    

  3. Добавьте базовый класс с именем 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.

    System_CAPS_ICON_note.jpg Примечание

    Если проект DLL собирается в командной строке, воспользуйтесь параметром компилятора /D, чтобы определить символ MATHFUNCSDLL_EXPORTS.

  4. В проекте MathFuncsDll в обозревателе решений в папке Исходные файлы откройте файл MathFuncsDll.cpp.

  5. Реализуйте функциональность класса 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;
        }
    }
    

  6. Скомпилируйте библиотеку динамической компоновки, выбрав Собрать решение в меню Сборка.

    System_CAPS_ICON_note.jpg Примечание

    При использовании выпуска Express, в котором не отображается меню Сборка, в строке меню выберите Сервис, Параметры, Расширенные параметры, чтобы включить это меню, а затем выберите Сборка, Собрать решение.

    System_CAPS_ICON_note.jpg Примечание

    При сборке проекта из командной строки используйте параметр компилятора /LD, указывающий на то, что выходной файл должен являться DLL-файлом. Для получения дополнительной информации см. /MD, /MT, /LD (использование библиотеки времени выполнения). Используйте параметр компилятора /EHsc для включения обработки исключений С++. Для получения дополнительной информации см. Параметр /EH (модель обработки исключений).

Создание приложения, ссылающегося на DLL

  1. Чтобы создать приложение С++, которое будет ссылаться и использовать созданную ранее библиотеку DLL, в меню Файл выберите пункт Создать и затем пункт Проект.

  2. В левой области в категории Visual C++ выберите Win32.

  3. В центральной области выберите Консольное приложение Win32.

  4. Укажите имя проекта, например MyExecRefsDll, в поле Имя. В раскрывающемся списке рядом с полем Решение выберите Добавить в решение. В результате новый проект будет добавлен в решение, содержащее библиотеку DLL. Нажмите кнопку ОК.

  5. На странице Обзор диалогового окна Мастер приложений Win32 нажмите кнопку Далее.

  6. На странице Параметры приложения выберите в поле Тип приложения пункт Консольное приложение.

  7. На странице Параметры приложения в разделе Дополнительные параметры снимите флажок Предкомпилированный заголовок.

  8. Нажмите кнопку Готово, чтобы создать проект.

Использование функциональности из библиотеки классов в приложении

  1. После создания консольного приложения будет создана пустая программа. Имя исходного файла будет совпадать с ранее выбранным именем. В этом примере он имеет имя MyExecRefsDll.cpp.

  2. Для использования в приложении математических процедур, созданных в библиотеке DLL, необходимо сослаться на эту библиотеку. Для этого в обозревателе решений выберите проект MyExecRefsDll, а затем в меню Проект выберите пункт Ссылки. В диалоговом окне Страницы свойств разверните узел Общие свойства, выберите .NET Framework и ссылки и нажмите кнопку Добавить новую ссылку. Дополнительные сведения о диалоговом окне Ссылки см. в разделе Добавление ссылок.

  3. В диалоговом окне Добавление ссылки перечислены библиотеки, на которые можно создать ссылку. На вкладке Проект перечислены все проекты текущего решения и включенные в них библиотеки, если они есть. Установите флажок рядом с MathFuncsDll на вкладке Проекты, а затем нажмите кнопку ОК.

  4. Для создания ссылки на файлы заголовка DLL необходимо изменить путь к каталогам включения. Для этого в диалоговом окне Окна свойств последовательно разверните узлы Свойства конфигурации и C/C++, а затем выберите Общие. В поле Дополнительные каталоги включаемых файлов укажите путь к месту размещения файла заголовка MathFuncsDll.h. Можно использовать относительный путь, например ..\MathFuncsDll\. Затем нажмите кнопку ОК.

  5. Теперь класс 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;
    }
    

  6. Соберите исполняемый файл, выбрав команду Собрать решение в меню Сборка.

Запуск приложения

  1. Убедитесь в том, что проект MyExecRefsDll выбран в качестве проекта по умолчанию. В обозревателе решений выберите MyExecRefsDll и затем в меню Проект выберите Назначить запускаемым проектом.

  2. Чтобы запустить проект, в строке меню выберите Отладка, Запуск без отладки. Результат выполнения должен выглядеть примерно следующим образом:

a + b = 106,4
a - b = -91,6
a * b = 732,6
a / b = 0,0747475
Перехвачено исключение: b не может быть равно нулю!

Visual C++ Guided Tour
DLL в Visual C++
Развертывание классических приложений
Пошаговое руководство. Развертывание программы (C++)
Вызов функций библиотек DLL из приложений Visual Basic

Показ: