Покажите, как создать DLL со строками на C++
Пробовала разные варианты создания на выходе файла DLL, который содержит несколько строк, поскольку изучаю C# — C++ непонятен совсем. Покажите пожалуйста код для создания C++ DLL, которая будет содержать пару строк (string или int), чтобы при обращении к ней, к определенному методу — возвращало ту или иную строку. Код:
File.h #include std::string String_One(); std::string String_Two(); File.cpp #include "Windows.h" #include "WowSuite.h" #include #include using namespace std; std::string String_One() < return "Hello, world!"; >std::string String_Two()
Так возможно?
Отслеживать
задан 19 окт 2016 в 5:40
681 4 4 серебряных знака 13 13 бронзовых знаков
А в чём беда _export char* getString()< return "Пара\nСтрок";>; и _export int getInt()
19 окт 2016 в 5:56
Остальное — опции компилятора. Проще всего проэкт — создать — с++ — dll библиотека (и в борланде и в студии и в многих других). В вопросе стоит указать вашу IDE или компилятор (если командной строкой создаёте) т.к в разных версиях и фирмах есть свои особенности. Возможно язык IDE (бывают русские и английские среды). Т.к. вы разработчик c# у вас MS visual studio? Английская? Какая версия 2005 или 2014?
19 окт 2016 в 5:59
для меня с++ это дремучий лес. Я не понимаю про заголовки, про создание функций, к которым я буду обращаться, все, что мне (желательно) нужно — это проект, в котором содержится метод, отображающий определенный текст(таких методов будет несколько.) После чего я хочу подключить эту библиотеку dll в c# и использовать метод, отображающий нужную мне строку
19 окт 2016 в 6:00
Для студии вот microsin.net/programming/pc/dll-building-and-using.html Если не подходит укажите какая у вас IDE.
19 окт 2016 в 6:09
Ссылка помогла создать dll файл, но я не понимаю ккак создать свой метод, который будет содержать строку, которую я хочу получить
19 окт 2016 в 6:22
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
#ifndef FILE_H #define FILE_H #if defined(MYLIBRARY) #define LIBRARY_EXPORT __declspec(dllexport) #else #define LIBRARY_EXPORT #endif #include std::string LIBRARY_EXPORT String_One(); std::string LIBRARY_EXPORT String_Two(); #endif // FILE_H
#include "file.h" std::string String_One() < return "Hello, world!"; >std::string String_Two()
При этом в проекте сборки dll, должен присутствовать DEFINE MYLIBRARY
Для Qt-creator для этого нужно в pro-файл добавить DEFINES += MYLIBRARY
В Visual Studio в настройках проекта С/С++ -> Preprocessor -> Preprocessor Definitions просто в конце добавить MYLIBRARY.
Стоит помнить, что библиотеки, в которых используются не только встроенные типы (char, int, float, double, bool, long), а и что-то другое(в том числе и std::string) требуют использования в основной программе(откуда загружается библиотека) использования того же компилятора, в случае с visual c++ еще и требуется соблюдения версии vc10, vc12, vc14 и пр. Так как разные компиляторы могут формировать разные имена экспортируемым функциям.
Если нужно использовать функции из других языков программирования, или с другим компилятором, или с помощью динамической загрузки библиотеки и использования GetProcAddress. То в h файле должны быть только объявления с использованием встроенных типов: (char, int, float, double, bool, long) и с добавлением extern «C», например:
#ifndef FILE_H #define FILE_H #if defined(MYLIBRARY) #define LIBRARY_EXPORT __declspec(dllexport) #else #define LIBRARY_EXPORT #endif extern "C" int LIBRARY_EXPORT Val_One(); extern "C" int LIBRARY_EXPORT Val_Two(); #endif // FILE_H
#include "file.h" int Val_One() < return 0; >int Val_Two()
Для того чтоб использовать функции в проекте c#^
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 < class Program < [DllImport("untitled.dll", EntryPoint = "Val_Two")] public static extern int func1(); static void Main(string[] args) < Console.WriteLine(func1()); Console.ReadKey(); >> >
При этом не забыть подложить untitled.dll в папку с программой c#
Создание библиотек DLL на C и C++ в Visual Studio
В Windows библиотека динамической компоновки (DLL) является исполняемым файлом, который выступает в качестве общей библиотеки функций и ресурсов. Динамическая компоновка — это возможность операционной системы. Она позволяет исполняемому файлу вызывать функции или использовать ресурсы, хранящиеся в отдельном файле. Эти функции и ресурсы можно компилировать и развертывать отдельно от использующих их исполняемых файлов.
Библиотека DLL не является отдельным исполняемым файлом. Библиотеки DLL выполняются в контексте приложений, которые их вызывают. Операционная система загружает библиотеку DLL в область памяти приложения. Это делается либо при загрузке приложения (неявная компоновка), либо по запросу во время выполнения (явная компоновка). Библиотеки DLL также упрощают совместное использование функций и ресурсов различными исполняемыми файлами. Несколько приложений могут осуществлять одновременный доступ к содержимому одной копии библиотеки DLL в памяти.
Различия между динамической и статической компоновкой
При статической компоновке весь код объектов копируется из статической библиотеки в использующие их исполняемые файлы во время сборки. При динамической компоновке включаются только те сведения, которые позволяют Windows найти и загрузить библиотеку DLL, содержащую элемент данных или функцию, во время выполнения. При создании библиотеки DLL также создается библиотека импорта, содержащая эту информацию. При сборке исполняемого файла, который вызывает библиотеку DLL, компоновщик использует экспортированные символы в библиотеке импорта, чтобы сохранить эти сведения для загрузчика Windows. Когда загрузчик загружает библиотеку DLL, она сопоставляется с областью памяти приложения. Для выполнения операций инициализации, необходимых библиотеке DLL, вызывается специальная функция DllMain из библиотеки DLL (если она имеется).
Различия между приложениями и библиотеками DLL
Хотя и библиотеки DLL, и приложения являются исполняемыми модулями, они отличаются некоторыми особенностями. Наиболее очевидное различие заключается в том, что библиотеку DLL нельзя запустить. С точки зрения системы, между приложениями и библиотеками DLL имеется два существенных различия.
- В системе может одновременно выполняться несколько экземпляров приложения. Экземпляр библиотеки DLL может быть только один.
- Приложение может загружаться как процесс. Ему могут принадлежать такие компоненты, как стек, потоки выполнения, глобальная память, дескрипторы файлов и очередь сообщений. У библиотеки DLL таких компонентов быть не может.
Преимущества использования библиотек DLL
Динамическая компоновка кода и ресурсов имеет некоторые преимущества над статической.
- Динамическая компоновка экономит память и сокращает подкачку. Многие процессы могут использовать библиотеку DLL совместно, одновременно обращаясь к одной доступной только для чтения копии ее частей в памяти. В отличие от этого, каждое приложение, созданное с помощью библиотеки статической компоновки, имеет полную копию кода библиотеки, которую система Windows должна загрузить в память.
- Динамическая компоновка экономит место на диске и пропускную способность. Несколько приложений могут совместно использовать одну копию библиотеки DLL на диске. В отличие от этого, каждое приложение, созданное с помощью библиотеки статической компоновки, имеет код библиотеки, связанный с исполняемым образом. Это увеличивает занимаемое на диске место и используемую для передачи данных пропускную способность.
- Обслуживание, применение исправлений для системы безопасности и обновление могут быть проще. Если приложения используют общие функции в библиотеке DLL, можно реализовать исправления ошибок и развернуть обновления для нее. При обновлении библиотек DLL использующие их приложения не нужно перекомпилировать или повторно компоновать. Они могут использовать новые библиотеки DLL сразу после их развертывания. В отличие от этого, при внесении исправлений в код статически скомпонованного объекта необходимо повторно скомпоновать и развернуть каждое использующее его приложение.
- С помощью библиотек DLL можно оказывать послепродажную поддержку. Например, библиотеку DLL драйвера дисплея можно изменить так, чтобы она поддерживала дисплей, который не был доступен на момент предоставления приложения.
- С помощью явной компоновки можно обнаруживать и загружать библиотеки DLL во время выполнения. Например, это могут быть расширения приложения, которые добавляют новые функциональные возможности без повторной сборки и развертывания приложения.
- Динамическая компоновка упрощает поддержку приложений, написанных на разных языках программирования. Программы, написанные на разных языках программирования, могут вызывать одну и ту же функцию в библиотеке DLL при условии соблюдения соглашения о ее вызове. Программы и функция DLL должны быть совместимы следующим образом: порядок, в котором функция ожидает передачи его аргументов в стек. выполнение очистки стека функцией или приложением; передача аргументов в регистрах.
- Динамическая компоновка обеспечивает механизм для расширения классов библиотеки Microsoft Foundation Classes (MFC). На основе существующих классов MFC можно создавать производные классы и помещать их в библиотеку расширения DLL, используемую приложениями MFC.
- Динамическая компоновка упрощает создание международных версий приложения. Библиотеки DLL — это удобный способ предоставления ресурсов для конкретных языковых стандартов, благодаря чему значительно упрощается создание международных версий приложения. Вместо предоставления множества локализованных версий приложения можно поместить строки и изображения для каждого языка в отдельную библиотеку DLL ресурсов. Затем приложение может загружать ресурсы для нужного языкового стандарта во время выполнения.
Возможный недостаток использования библиотек DLL заключается в том, что приложения не автономны. Они требуют наличия отдельного модуля DLL, которое должно проверяться в процессе установки.
Дополнительные сведения о создании и использовании библиотек DLL
В приведенных ниже статьях приводятся подробные сведения о создании библиотек DLL на C и C++ в Visual Studio.
Пошаговое руководство. Создание и использование библиотеки DLL (C++)
Описывает создание и использование библиотек DLL при помощи Visual Studio.
Виды библиотек DLL
Предоставляет сведения о различных типах библиотек DLL, которые доступны для сборки.
Вопросы и ответы по библиотекам DLL
Ответы на часто задаваемые вопросы о библиотеках DLL.
Связывание исполняемого файла с библиотекой DLL
Описание явного и неявного соединения с библиотекой DLL.
Инициализация библиотеки DLL
Описывается код инициализации библиотеки DLL, который должен выполняться при загрузке библиотеки DLL.
Библиотеки DLL и поведение библиотеки времени выполнения Visual C++
Описывается последовательность запуска библиотеки DLL средой выполнения.
Функции LoadLibrary и AfxLoadLibrary
Описывается использование функций LoadLibrary и AfxLoadLibrary для явной связи с библиотекой DLL во время выполнения.
Функция GetProcAddress
Описывается использование GetProcAddress для получения адреса экспортированной функции в DLL.
Функции FreeLibrary и AfxFreeLibrary
Описывается использование функций FreeLibrary и AfxFreeLibrary , когда модуль DLL больше не нужен.
Порядок поиска библиотеки динамической компоновки (DLL)
Описание пути поиска, который операционная система Windows использует для поиска библиотеки DLL в системе.
Состояния модулей обычной библиотеки DLL MFC, динамически связанной с MFC
Описываются состояния модулей обычной библиотеки DLL, динамически связываемой с MFC.
Библиотеки DLL для расширения MFC
Описываются библиотеки DLL, которые обычно реализуют классы многократного использования, производные от существующих классов MFC.
Создание библиотек DLL, содержащих только ресурсы
Библиотека DLL, содержащая только ресурсы, например значки, растровые изображения, строки и диалоговые окна.
Локализованные ресурсы в приложениях MFC: вспомогательные библиотеки DLL
Расширенная поддержка библиотек спутниковой связи DLL и содержит возможность, которая позволяет создавать приложения, локализированные на различные языки.
Импорт и экспорт
Импортирование открытых символов в приложение или экспортирование функций из библиотеки DLL
Технология Active и библиотеки DLL
Размещение серверов объектов внутри библиотеки DLL.
Автоматизация в библиотеке DLL
Параметр автоматизации в решениях мастера библиотек DLL MFC.
Соглашения об именовании библиотек DLL MFC
Способ встраивания библиотек DLL в MFC, опираясь на четко структурированное соглашение об именовании.
Связанные разделы
Использование MFC как части библиотеки DLL
Описываются постоянные библиотеки DLL MFC, которые позволяют использовать библиотеку MFC как часть библиотеки динамической компоновки Windows.
Версия библиотеки DLL MFC
Описывается механизм использования общих библиотек динамической компоновки MFCxx.dll и MFCxxD.dll (где x является номером версии MFC) с приложениями MFC и расширениями библиотек DLL MFC.
Статья Как создать dll библиотеку?
Очень часто в своей работе, Вы будете сталкиваться с такой ситуацией.
Перед вами стоит задача, нужно написать программу » Супер Блокнот» которая должна сохранить все функции стандартного блокнота, но при этом иметь ряд каких-то дополнительных функций, благодаря которым, при выборе программы для работы с текстом, пользователь будет отдавать предпочтение именно вашей программе. Для этого было решено добавить несколько новых функций, одна из них, будет отвечать за подсчет и вывод количества слов в тексте.
Через пару недель программа была написана, затем она попала в Интернет, пользователи оценили новый продукт и стали им пользоваться. Цель достигнута.
Проходит время и перед вами ставят новую задачу, написать программу «Супер парсер«. Одной из функции данной программы, будет подсчет слов в тексте. Вы понимаете, что снова придется разрабатывать метод, который будет вести подсчёт слов. Но, при этом вспоминаете, что совсем не давно уже разрабатывали программу, в которой применялась данная функция. Чтобы не изобретать велосипед, Вы открываете исходник программы «Супер блокнот«; и копируете весь метод в исходник новой программы «Супер парсер«. Отлично, теперь Вам не придется тратить время на написание этого метода заново, и Вы можете посветить больше времени остальным элементам программы. Задача решена.
Но, что если метод по подсчету слов, писали не Вы, а допустим, какой-нибудь коллега по работе и по каким-то причинам, Вы не можете получить доступ к исходному коду программы «Супер блокнот«. То есть первый вариант, копирование метода из исходника, не прокатит и данный метод придется писать самому ммм, печалька.
Но, тут вам звонит ваш коллега по работе и говорит: Ты знаешь, я тут вспомнил, когда я разрабатывал данный метод, я подумал, что возможно мне придется его использовать ещё где-то, и по этому я решил вынести его в отдельную сборку, в виде файла динамической библиотеки (dll).Ты просто скопируй этот файл dll в свой проект, и подключи его, как внешнюю сборку, после чего ты получишь доступ к моему методу и сможешь им пользоваться.
Отлично! Вы проделываете все описанные действия, в программе “Супер парсер” появляется нужный метод, задача решена и вам вновь не пришлось повторно писать код руками.
На этом присказка закончена и теперь переходим к более подробному изучению.
Что такое DLL
DLL (dynamic-link library) — это динамически подключаемая библиотека, или сокращено динамическая библиотека.
Как уже писал ранее, динамические библиотеки, позволяют повторно использовать ранее написанный код, а так же они обеспечивают лучшую переносимость кода. Достаточно, скинуть файл на флешку, или скачать dll файл из Интернета, после чего добавить его в текущий проект и тут же получить набор разных дополнительных функций для вашего приложения. Так же стоит знать, что в одном dll файле может храниться любое количество типов, членов и пространств имён.
Создание файла dll
Для начала выберем тип нового создаваемого приложения, а точнее проекта.
Выбираем Class Library, то есть создаем файл динамической библиотеки (dll)
Так же Вы можете указать, под какую версию Фреймворка будет создаваться данный проект.
После того, как Visual Studio создаст каркас проекта, Вы увидите следующее:
Так будет выглядеть окно Solution Explorer
А так будет выглядеть рабочая область, где Вы обычно пишите код программы
И так дано пространство имён: Car и класс: Class1. Class1 не удачное название, давайте немного изменим наш код, заменив Class1 на BMW, и добавим метод, который будет выводить имя нашего класса.
И так код написан, и теперь необходимо выполнить компиляцию, чтобы получить сборку.
Если сейчас попытаться нажать F5 или Ctrl+F5, то вы увидите данное окно
A project with an Output type of Class Library cannot be started directly
Данная ошибка, говорит лишь о том, что был создан файл динамической библиотеки (dll), а не исполняемый файл (exe), который не может быть запущен.
Для того, чтобы скомпилировать проект, нажмите клавишу F6, после чего в директории bin\Debug появиться файл Car.dll.
Чтобы проверить был ли создан файл библиотеки, воспользуйтесь кнопкой Show All Files на вкладке Solution Explorer
Сборка, в виде файла динамической библиотеки успешно создана.
Теперь перейдем в папку bin\Debug, для того, чтобы быстро переместиться в текущую директорию проекта, в том же Solution Explorer воспользуйтесь пунктом Open Folder in Windows Explorer
Скопируйте полученный файл сборки (в нашем случае — это файл Car.dll) в какую-нибудь временную папку. На самом деле, это делать необязательно, Вы можете оставить данный файл в этой папке, но для удобства, создадим новую папку, и поместим туда созданный файл библиотеки.
После чего закроем текущий проект и создадим новый. Но, на этот раз выберем тип проекта — консольное приложение.
Создаем новый проект.
Новый проект создан. Теперь подключим в текущий проект, нашу библиотеку (Car.dll)
Подключение dll
Для этого на папке References, в окне Solution Explorer нужно нажать правую кнопку мыши и выбрать пункт Add Reference, откроется вот такое окно:
- Выберите вкладку Browse
- Укажите папку, в которой лежит файл созданной библиотеки (в нашем примере — Car.dll)
- Выделите файл нужной библиотеки и нажмите кнопку ОК;
На ней видно, что в наш текущий проект была успешна, добавлена ссылка на нашу сборку Car.dll, в которой храниться наш код на языке IL. Надеюсь, Вы помните, что после компиляции весь написанный вами код преобразуется в промежуточный код на языке IL (CIL, MSIL — это одно и тоже). А так же видно, что в папку bin\Debug была помещёна копия нашей библиотеки.
Если вдруг Вы забыли, какое пространство имен, типы, или члены содержит ваша созданная библиотека. Вы всегда можете воспользоваться таким инструментом Visual Studio, как Object Browser. Для этого перейдите на вкладку Solution Explorer, откройте папку References, и просто щёлкните правой кнопкой мыши по добавленной ранее библиотеке, в нашем случае напоминаю — это файл (Car.dll) и выберите пункт View in Object Browser, появиться вот такое окно.
В окне Object Browser можно посмотреть содержимое нашей сборки.
Сборка подключена и теперь Вы можете работать с её содержимым. Далее выполним необязательный пункт.
Добавим, с помощью ключевого слова using пространство имен Car из созданной нами библиотеки Car.dll, после чего создадим объект класса BMW и выполним метод Вывести_Имя_Класса().
- Создаем файл динамической библиотеки (dll)
- Подключаем созданную библиотеку в наш проект, путем добавления в папку References ссылки на наш файл dll.
- (Необязательный пункт) Подключаем пространство имен из подключенной сборки, с помощью ключевого слова using, либо используем полное наименование, то есть Пространство имён.Тип (Car.BMW).
- Profit
И в конце не много информации о типах сборок:
Сборки бывают следующих основных видов: общие и частные.
Частная сборка (private assembly)
Это файлы библиотек, как наш ранее созданный файл Car.dll, которые содержаться на протяжении всего времени в каталоге текущего приложения или любом из его подкаталогов.
Вернёмся к началу статьи.
После того, как было создано приложение “Супер парсер”, мы получили сборку в виде файла (exe). Затем мы решили протестировать нашу программу и отдаём её нашему другу, при этом Вы так же упоминаете, что если он хочет иметь дополнительные функции в программе, то ему нужно просто рядом с его exe файлом поместить файл библиотеки Car.dll. После чего он получит возможность подсчёта слов в тексте. То есть библиотека будет храниться в той же директории, что и исполняемый файл.
Общие сборки (shared assembly)
Это сборки, предназначенные для множественного использования разными приложениями, установленными на одном компьютере.
К примеру, у нас есть две программы. Которые будет использовать наш файл Car.dll, чтобы не копировать данный файл в каждую папку, мы можем поместить его в специальное место, которое называется Global Assembly Cache — (GAC) или глобальный кэш сборок. Теперь сборка будет храниться в одном специальном месте, и ваши программа всегда будут знать, где можно найти данную библиотеку кода. Если бы мы воспользовались приватным способом, то нам бы пришлось поместить нашу библиотеку, в каждую папку того приложения, с которым она должна взаимодействовать.
Пошаговое руководство. Создание и использование собственной библиотеки динамических ссылок (C++)
В этом пошаговом руководстве показано, как с помощью интегрированной среды разработки (IDE) Visual Studio создать собственную библиотеку динамической компоновки (DLL), написанную на Microsoft C++ (MSVC). Далее в нем показано, как использовать библиотеку DLL из другого приложения C++. Библиотеки DLL (также называемые общими библиотеками в операционных системах на основе UNIX) являются одним из наиболее полезных компонентов Windows. Их можно использовать для обмена кодом и ресурсами, а также для уменьшения размера своих приложений. Библиотеки DLL могут упростить обслуживание и расширение приложений.
В этом пошаговом руководстве вы создадите библиотеку DLL, которая реализует некоторые математические функции. Затем вы создадите консольное приложение, использующее функции из библиотеки DLL. Попутно вы познакомитесь с некоторыми методами программирования и соглашениями, используемыми в библиотеках DLL для Windows.
В этом пошаговом руководстве рассматриваются следующие задачи:
- Создание проекта библиотеки DLL в Visual Studio.
- Добавление экспортированных функций и переменных в библиотеку DLL.
- Создание проекта «Консольное приложение» в Visual Studio.
- Использование в консольном приложении функций и переменных, импортированных из библиотеки DLL.
- Запустите готовое приложение.
Как и в случае со статически связанной библиотекой, библиотека DLL экспортирует переменные, функции и ресурсы по имени. Клиентское приложение импортирует имена для использования этих переменных, функций и ресурсов. В отличие от статически компонуемой библиотеки, Windows соединяет импорт в вашем приложении с экспортом в библиотеку DLL во время загрузки или выполнения, а не во время компоновки. Для выполнения этих подключений Windows требуются дополнительные сведения, которые не являются частью стандартной модели компиляции C++. Чтобы предоставить эти дополнительные сведения, компилятор MSVC реализует некоторые специальные расширения Майкрософт для C++. Мы рассмотрим эти расширения далее.
В этом пошаговом руководстве создаются два решения Visual Studio. Первое решение создает библиотеку DLL, а второе — клиентское приложение. Библиотека DLL использует соглашение о вызовах языка C. Ее можно вызывать из приложений, написанных на других языках программирования, при условии, что платформа, соглашения о вызовах и соглашения о связывании совпадают. Клиентское приложение использует неявную компоновку, в рамках которой Windows связывает приложение с библиотекой DLL во время загрузки. Эта компоновка позволяет приложению вызывать функции, предоставляемые библиотекой DLL, точно так же, как функции в библиотеке статической компоновки.
В этом пошаговом руководстве не рассматриваются некоторые общие ситуации. В нем не рассматривается использование библиотеки DLL для C++ другими языками. Он не показывает, как создавать DLL-библиотеки только для ресурсов или как использовать явную компоновку для загрузки библиотек DLL во время выполнения, а не во время загрузки. Уверяем вас, все это можно выполнять с помощью MSVC и Visual C++.
Несмотря на то что код библиотеки DLL написан на языке C++, мы использовали интерфейсы в стиле C для экспортированных функций. Существует две основные причины: во-первых, многие другие языки поддерживают импорт функций в стиле C. Клиентское приложение не должно быть записано на языке C++. Во-вторых, это позволяет избежать некоторых распространенных ошибок, связанных с экспортируемыми классами и функциями-членами. При экспорте классов легко диагностировать ошибки, так как все, что упоминалось в объявлении класса, должно иметь экземпляр, который также экспортирован. Это ограничение применяется к библиотекам DLL, но не к статическим библиотекам. Если классы имеют обычный стиль данных, вы не должны столкнуться с этой проблемой.
Ссылки на дополнительные сведения о DLL см. в статье Создание библиотек DLL на C/C++ в Visual Studio. Дополнительные сведения о явной и неявной компоновке см. в разделе Определение подходящего метода связывания. Дополнительные сведения о создании библиотек DLL C++ для использования с языками, в которых применяются соглашения о компоновках языка C, см. в статье Экспорт функций на языке C++ для использования в исполняемых модулях, исходный код которых написан на языке C. Дополнительные сведения о том, как создавать библиотеки DLL для использования с языками .NET, см. в статье Вызов функций библиотек DLL из приложений Visual Basic.
Необходимые компоненты
- Компьютер под управлением Microsoft Windows 7 или более поздних версий. Мы рекомендуем использовать последнюю версию Windows для более удобной разработки.

- копия Visual Studio. Сведения о скачивании и установке Visual Studio см. в этой статье. Когда вы запускаете установщик, убедитесь, что установлена рабочая нагрузка Разработка классических приложений на C++. Не беспокойтесь, если вы не установили эту рабочую нагрузку при установке Visual Studio. Вы можете снова запустить установщик и установить ее сейчас.
- копия Visual Studio. Сведения о скачивании и установке Visual Studio 2015 см. в разделе Установка Visual Studio 2015. Для установки компилятора и средств используйте выборочную установку C++, так как они не установлены по умолчанию.
- Базовые значения об использовании интегрированной среды разработки Visual Studio. Если вы уже использовали классические приложения для Windows, вы, вероятно, справитесь. Общие сведения см. в обзоре возможностей интегрированной среды разработки Visual Studio.
- Основные навыки владения языком C++. Не волнуйтесь, мы не будем делать ничего сложного.
В данном пошаговом руководстве подразумевается, что вы используете Visual Studio 2017 версии 15.9 или более поздней. В некоторых более ранних версиях Visual Studio 2017 имелись дефекты в шаблонах кода или использовались разные диалоговые окна пользовательского интерфейса. Чтобы избежать проблем, используйте Visual Studio Installer для обновления Visual Studio 2017 до версии 15.9 или более поздней.
Создание проекта библиотеки DLL
Этот набор задач позволяет создать проект для библиотеки DLL, добавить код и выполнить его сборку. Для начала запустите IDE Visual Studio и выполните вход, если это необходимо. Инструкции немного отличаются в зависимости от используемой версии Visual Studio. Убедитесь, что в элементе управления в верхнем левом углу этой страницы выбрана правильная версия.
Создание проекта библиотеки DLL в Visual Studio 2019

- В строке меню выберите Файл>Создать>Проект, чтобы открыть диалоговое окно Создание проекта.
- В верхней части диалогового окна для параметра Язык установите значение C++, для параметра Платформа — значение Windows, а для параметра Тип проекта — значение Библиотека.
- В отфильтрованном списке типов проектов щелкните Библиотека динамической компоновки (DLL), а затем нажмите кнопку Далее.
- На странице Настроить новый проект введите MathLibrary в поле Имя проекта. Примите заданные по умолчанию Расположение и Имя решения. Для параметра Решение задайте Создать новое решение. Снимите флажок Разместить решение и проект в одном каталоге, если он установлен.
- Нажмите кнопку Создать, чтобы создать проект.
После создания решения созданный проект вместе с исходными файлами отобразится в окне обозревателя решений в Visual Studio.

Создание проекта библиотеки DLL в Visual Studio 2017

- В строке меню последовательно выберите пункты Файл>Создать>Проект, чтобы открыть диалоговое окно Новый проект.
- На панели слева в диалоговом окне Новый проект выберите Установленные >Visual C++ >Классическое приложение для Windows. В центральной области выберите Библиотека динамической компоновки (DLL). В поле Имя введите MathLibrary. Примите заданные по умолчанию Расположение и Имя решения. Для параметра Решение задайте Создать новое решение. Установите флажок Создать каталог для решения, если он снят.
- Нажмите кнопку ОК, чтобы создать проект.
После создания решения созданный проект вместе с исходными файлами отобразится в окне обозревателя решений в Visual Studio.

Создание проекта библиотеки DLL в Visual Studio 2015 и более ранних версий
- В строке меню выберите Файл >Создать >Проект.
- В левой области диалогового окна Новый проект разверните узлы Установленные>Шаблоны и выберите Visual C++, а затем в центральной области щелкните Консольное приложение Win32. В поле Имя введите MathLibrary. Примите заданные по умолчанию Расположение и Имя решения. Для параметра Решение задайте Создать новое решение. Установите флажок Создать каталог для решения, если он снят.

- Нажмите кнопку ОК, чтобы закрыть диалоговое окно Новый проект, и запустите мастер приложений Win32.

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

- Нажмите кнопку Готово , чтобы создать проект.
Когда мастер завершит создание решения, вы сможете увидеть созданный проект вместе с исходными файлами в окне обозревателя решений в Visual Studio.

Пока эта библиотека DLL ничего не делает. Затем вы создадите файл заголовка для объявления функций, экспортируемых вашей библиотекой DLL, и добавите определения функций в библиотеку DLL, чтобы сделать ее более полезной.
Добавление файла заголовка в библиотеку DLL
- Чтобы создать файл заголовка для функций, последовательно щелкните Проект>Добавить новый элемент.
- В диалоговом окне Добавление нового элемента в левой области щелкните Visual C++. В центральной области выберите Заголовочный файл (.h). Укажите MathLibrary.h в качестве имени для файла заголовка.

- Нажмите кнопку Добавить, чтобы создать пустой файл заголовка, который отображается в новом окне редактора.

- Замените все содержимое этого файла заголовка следующим кодом:
// MathLibrary.h - Contains declarations of math functions #pragma once #ifdef MATHLIBRARY_EXPORTS #define MATHLIBRARY_API __declspec(dllexport) #else #define MATHLIBRARY_API __declspec(dllimport) #endif // The Fibonacci recurrence relation describes a sequence F // where F(n) is < n = 0, a // < n = 1, b // < n >1, F(n-2) + F(n-1) // for some initial integral values a and b. // If the sequence is initialized F(0) = 1, F(1) = 1, // then this relation produces the well-known Fibonacci // sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, . // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. extern "C" MATHLIBRARY_API void fibonacci_init( const unsigned long long a, const unsigned long long b); // Produce the next value in the sequence. // Returns true on success and updates current value and index; // false on overflow, leaves current value and index unchanged. extern "C" MATHLIBRARY_API bool fibonacci_next(); // Get the current value in the sequence. extern "C" MATHLIBRARY_API unsigned long long fibonacci_current(); // Get the position of the current value in the sequence. extern "C" MATHLIBRARY_API unsigned fibonacci_index();
Этот файл заголовка объявляет некоторые функции для создания обобщенной последовательности Фибоначчи, исходя из двух начальных значений. Вызов fibonacci_init(1, 1) создает знакомую последовательность чисел Фибоначчи.
Обратите внимание на операторы препроцессора в верхней части файла. Новый шаблон проекта библиотеки DLL добавляется _EXPORTS к определенным макросам препроцессора. В этом примере Visual Studio определяет MATHLIBRARY_EXPORTS , когда создается проект DLL MathLibrary.
MATHLIBRARY_EXPORTS При определении MATHLIBRARY_API макроса макрос задает __declspec(dllexport) модификатор для объявлений функций. Этот модификатор предписывает компилятору и компоновщику экспортировать функцию или переменную из библиотеки DLL для использования другими приложениями. Если не определено, например, если MATHLIBRARY_EXPORTS файл заголовка включен клиентским приложением, MATHLIBRARY_API применяет __declspec(dllimport) модификатор к объявлениям. Этот модификатор оптимизирует импорт функции или переменной в приложении. Дополнительные сведения см. в статье dllexport, dllimport.
Добавление реализации в библиотеку DLL
- В обозревателе решений щелкните узел Файлы решения правой кнопкой мыши и выберите пункты Добавить >Новый элемент. Создайте новый CPP-файл с именем MathLibrary.cpp, аналогично добавлению нового файла заголовка на предыдущем шаге.
- В окне редактора выберите вкладку MathLibrary.cpp, если она уже открыта. Если нет, то в обозревателе решений дважды щелкните файл MathLibrary.cpp в папке Исходные файлы проекта MathLibrary.
- В редакторе замените содержимое файла MathLibrary.cpp следующим кодом:
// MathLibrary.cpp : Defines the exported functions for the DLL. #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier #include #include #include "MathLibrary.h" // DLL internal state variables: static unsigned long long previous_; // Previous value, if any static unsigned long long current_; // Current sequence value static unsigned index_; // Current seq. position // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. void fibonacci_init( const unsigned long long a, const unsigned long long b) < index_ = 0; current_ = a; previous_ = b; // see special case when initialized >// Produce the next value in the sequence. // Returns true on success, false on overflow. bool fibonacci_next() < // check to see if we'd overflow result or position if ((ULLONG_MAX - previous_ < current_) || (UINT_MAX == index_)) < return false; >// Special case when index == 0, just return b value if (index_ > 0) < // otherwise, calculate next sequence value previous_ += current_; >std::swap(current_, previous_); ++index_; return true; > // Get the current value in the sequence. unsigned long long fibonacci_current() < return current_; >// Get the current index position in the sequence. unsigned fibonacci_index()
- В окне редактора выберите вкладку MathLibrary.cpp, если она уже открыта. Если нет, то в обозревателе решений дважды щелкните файл MathLibrary.cpp в папке Исходные файлы проекта MathLibrary.
- В редакторе замените содержимое файла MathLibrary.cpp следующим кодом:
// MathLibrary.cpp : Defines the exported functions for the DLL. #include "stdafx.h" // use pch.h in Visual Studio 2019 and later #include #include #include "MathLibrary.h" // DLL internal state variables: static unsigned long long previous_; // Previous value, if any static unsigned long long current_; // Current sequence value static unsigned index_; // Current seq. position // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. void fibonacci_init( const unsigned long long a, const unsigned long long b) < index_ = 0; current_ = a; previous_ = b; // see special case when initialized >// Produce the next value in the sequence. // Returns true on success, false on overflow. bool fibonacci_next() < // check to see if we'd overflow result or position if ((ULLONG_MAX - previous_ < current_) || (UINT_MAX == index_)) < return false; >// Special case when index == 0, just return b value if (index_ > 0) < // otherwise, calculate next sequence value previous_ += current_; >std::swap(current_, previous_); ++index_; return true; > // Get the current value in the sequence. unsigned long long fibonacci_current() < return current_; >// Get the current index position in the sequence. unsigned fibonacci_index()
Чтобы убедиться, что все работает, скомпилируйте библиотеку динамической компоновки. Чтобы выполнить компиляцию, последовательно выберите Сборка>Собрать решение. Библиотека DLL и связанные выходные данные компилятора помещаются в папку с именем Debug непосредственно под папкой решения. При создании сборки выпуска выходные данные помещаются в папку с именем Release. Результат должен выглядеть следующим образом.
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------ 1>pch.cpp 1>dllmain.cpp 1>MathLibrary.cpp 1>Generating Code. 1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp 1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------ 1>stdafx.cpp 1>dllmain.cpp 1>MathLibrary.cpp 1>Generating Code. 1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp 1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------ 1>MathLibrary.cpp 1>dllmain.cpp 1>Generating Code. 1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp 1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll 1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.pdb (Partial PDB) ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Поздравляем, вы создали библиотеку DLL с помощью Visual Studio! Далее вы создадите клиентское приложение, которое использует функции, экспортируемые из библиотеки DLL.
Создание клиентского приложения, которое использует библиотеку DLL
При создании библиотеки DLL подумайте о том, как клиентские приложения могут его использовать. Чтобы вызвать функции или получить доступ к данным, экспортированным библиотекой DLL, исходный код клиента должен иметь объявления, доступные во время компиляции. Во время компоновки компоновщику требуются сведения для разрешения вызовов функций или доступа к данным. Библиотека DLL предоставляет эти сведения в библиотеке импорта — файле, который содержит сведения о поиске функций и данных вместо фактического кода. Во время выполнения библиотека DLL должна быть доступна клиенту в месте, которое может найти операционная система.
Независимо от того, является ли он вашим или предоставлен сторонним разработчиком, вашему проекту клиентского приложения требуется несколько фрагментов информации для использования библиотеки DLL. Ему необходимо найти заголовки, в которых объявляются экспорты библиотеки DLL, библиотеки импорта для компоновщика и сама библиотека DLL. Одним из решений является копирование всех этих файлов в ваш клиентский проект. Для сторонних библиотек DLL, которые вряд ли изменятся во время разработки вашего клиента, этот метод может быть лучшим способом их использования. Однако, когда вы также создаете библиотеку DLL, лучше избегать дублирования. Если вы делаете локальную копию файлов библиотеки DLL, которые находятся в стадии разработки, вы можете случайно изменить файл заголовка только в одной копии или использовать устаревшую библиотеку.
Чтобы избежать рассинхронизации, мы рекомендуем вам установить путь включения в своем клиентском проекте, чтобы добавить файлы заголовков библиотеки DLL напрямую из проекта DLL. Кроме того, укажите путь к библиотеке в своем клиентском проекте, чтобы добавить библиотеки импорта DLL из проекта DLL. Наконец, скопируйте встроенную библиотеку DLL из проекта DLL в выходной каталог своей сборки клиента. Этот шаг позволяет вашему клиентскому приложению использовать тот же код библиотеки DLL, который вы создали.
Создание клиентского приложения в Visual Studio

- В строке меню выберите «Файл>нового проекта«>, чтобы открыть диалоговое окно «Создать проект».
- В верхней части диалогового окна задайте для параметра Язык значение C++, для параметра Платформа значение Windows, а для Типа проекта — Консоль.
- В отфильтрованном списке типов проектов щелкните Консольное приложение, а затем нажмите кнопку Далее.
- На странице Настроить новый проект введите MathClient в поле Имя проекта. Примите заданные по умолчанию Расположение и Имя решения. Для параметра Решение задайте Создать новое решение. Снимите флажок Разместить решение и проект в одном каталоге, если он установлен.
- Нажмите кнопку Создать, чтобы создать клиентский проект.
Создается минимальный проект консольного приложения. Имя главного исходного файла будет совпадать с ранее введенным именем проекта. В этом примере используется имя MathClient.cpp. Вы можете создать проект, но он еще не использует вашу библиотеку DLL.
Создание клиентского приложения в Visual Studio 2017

Теперь можно добавить файл MathLibrary.h и использовать функции, которые он объявляет, в вашем клиентском приложении. Замените содержимое файла MathClient.cpp, используя следующий код:
// MathClient.cpp : Client app for MathLibrary DLL. // #include "pch.h" Uncomment for Visual Studio 2017 and earlier #include #include "MathLibrary.h" int main() < // Initialize a Fibonacci relation sequence. fibonacci_init(1, 1); // Write out the sequence values until overflow. do < std::cout while (fibonacci_next()); // Report count of values written before overflow. std::cout
Этот код может быть скомпилирован, но не скомпилирован. Если вы создаете клиентское приложение, в списке ошибок появится несколько ошибок LNK2019. Это связано с отсутствием некоторых сведений о проекте: вы еще не указали, что проект зависит от библиотеки MathLibrary.lib . И вы не указали компоновщику, как найти файл MathLibrary.lib.
Чтобы устранить эту проблему, можно скопировать файл библиотеки непосредственно в проект клиентского приложения. Компоновщик сможет найти и использовать его автоматически. Однако если и библиотека, и клиентское приложение находятся в стадии разработки, это может привести к изменениям в одной копии, которые не будут отображаться в другой. Чтобы избежать этой проблемы, можно задать свойство Дополнительные зависимости, чтобы сообщить системе сборки о том, что проект зависит от MathLibrary.lib. Также можно задать путь Дополнительные каталоги библиотек в проекте, включив в него путь к исходной библиотеке при компоновке.
Добавление библиотеки импорта DLL в проект
- Щелкните правой кнопкой мыши узел MathClient в обозревателе решений и выберите Свойства, чтобы открыть диалоговое окно Страницы свойств.
- В раскрывающемся списке Конфигурация выберите пункт Все конфигурации, если он еще не выбран. Это гарантирует, что любые изменения свойств применяются к сборкам отладки и выпуска.
- В области слева выберите пункт Свойства конфигурации >Компоновщик>Ввод. На панели свойств щелкните раскрывающийся элемент управления рядом с полем ввода параметра Дополнительные зависимости, а затем щелкните Правка.

- В диалоговом окне Дополнительные зависимости добавьте MathLibrary.lib в список в верхнем элементе управления "Поле ввода".

- Нажмите кнопку OK, чтобы вернуться в диалоговое окно Страницы свойств.
- В области слева выберите пункт Свойства конфигурации >Компоновщик>Общие. На панели свойств щелкните раскрывающийся элемент управления рядом с полем ввода параметра Дополнительные каталоги библиотек, а затем щелкните Правка.

- Дважды щелкните в верхней панели диалогового окна Дополнительные каталоги библиотек, чтобы включить элемент управления "Поле ввода". В элементе управления "Поле ввода" укажите путь к расположению файла MathLibrary.lib. По умолчанию он находится в папке с именем Debug непосредственно в папке решения DLL. При создании сборки выпуска файл помещается в папку с именем Release. Можно использовать макрос $(IntDir) , чтобы компоновщик мог найти библиотеку DLL независимо от типа создаваемой сборки. Если вы следовали инструкциям по размещению клиентского проекта в отдельном решении, отличном от проекта DLL, относительный путь должен выглядеть следующим образом: ..\..\MathLibrary\$(IntDir) Если библиотеки DLL и клиентские проекты находятся в других расположениях, измените относительный путь для соответствия.

- Как только вы ввели путь к файлу библиотеки, в диалоговом окне Дополнительные каталоги библиотек нажмите кнопку ОК, чтобы вернуться в диалоговое окно Страницы свойств. Нажмите ОК, чтобы сохранить изменения свойств.
Ваше клиентское приложение теперь можно компилировать и компоновать, но в нем по-прежнему нет всего необходимого для запуска. Когда операционная система загружает ваше приложение, оно ищет библиотеку DLL MathLibrary. Если она не может найти библиотеку DLL в определенных системных каталогах, в пути среды или локальном каталоге приложения, загрузка завершается сбоем. В зависимости от операционной системы вы увидите сообщение об ошибке следующего вида:

Чтобы избежать этой проблемы, можно скопировать библиотеку DLL в каталог, в котором находится исполняемый файл клиента, в процессе сборки. Можно добавить событие после сборки в ваш проект, чтобы добавить команду, которая копирует библиотеку DLL в выходной каталог вашей сборки. Указанная здесь команда копирует библиотеку DLL только в том случае, если она отсутствует или была изменена. Он использует макросы для копирования в расположения отладки или выпуска на основе конфигурации сборки.
Копирование библиотеки DLL в событие после сборки

- Щелкните правой кнопкой мыши узел MathClient в обозревателе решений и выберите Свойства, чтобы открыть диалоговое окно Страницы свойств.
- В раскрывающемся списке Конфигурация выберите пункт Все конфигурации, если он еще не выбран.
- В области слева выберите Свойства конфигурации >События сборки >Событие после сборки.
- В области свойств щелкните элемент управления "Поле ввода" в поле Командная строка. Если вы следовали инструкциям по размещению клиентского проекта в отдельном решении, отличном от проекта DLL, введите следующую команду: xcopy /y /d "..\..\MathLibrary\$(IntDir)MathLibrary.dll" "$(OutDir)" Если библиотеки DLL и клиентские проекты находятся в других каталогах, измените относительный путь к библиотеке DLL для соответствия.
- Нажмите кнопку OK, чтобы сохранить изменения в свойствах проекта.
Теперь в вашем клиентском приложении есть все, что нужно для сборки и запуска. Соберите приложение, щелкнув команду Сборка>Собрать решение в меню. Окно Вывод в Visual Studio должно иметь примерно следующий вид в зависимости от используемой версии Visual Studio:
1>------ Build started: Project: MathClient, Configuration: Debug Win32 ------ 1>MathClient.cpp 1>MathClient.vcxproj -> C:\Users\username\Source\Repos\MathClient\Debug\MathClient.exe 1>1 File(s) copied ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Поздравляем, вы создали приложение, которое вызывает функции в вашей библиотеке DLL. Теперь запустите свое приложение, чтобы увидеть, как оно работает. В строке меню щелкните Отладка>Начать без отладки. В Visual Studio открывается командное окно для запуска программы. Последняя часть выходных данных должна выглядеть так:

Для закрытия командного окна нажмите любую клавишу.
Теперь, когда вы создали библиотеку DLL и клиентское приложение, вы можете экспериментировать. Попробуйте задать точки останова в коде клиентского приложения и запустите приложение в отладчике. Посмотрите, что происходит, когда вы входите в вызов библиотеки. Добавьте другие функции в библиотеку или напишите другое клиентское приложение, которое использует вашу библиотеку DLL.
При развертывании приложения необходимо также развернуть используемые им библиотеки DLL. Самый простой способ сделать библиотеки DLL, которые вы создаете или добавляете из сторонних источников, доступными — поместить их в тот же каталог, что и ваше приложение. Это также называется локальным развертыванием приложений. Дополнительные сведения о развертывании см. в разделе Deployment in Visual C++.