Как же подключить/загрузить внешнюю динамическую библиотеку в свою программу/проект, написанную на языке программирования C++ в IDE Microsoft Visual Studio, в ОС Microsoft Windows?
Состав
Типы файлов
Для начала, давайте разберёмся, что обычно представляет собой любая динамическая библиотека, написанная на, и созданная для программ С++? Это от 1 до 4 типов файлов:
- Some.h — заголовочный файл, который объявляет функционал библиотеки, i.e., заголовочный текстовый файл с определениями всех доступных сущностей (переменных, констант, классов, методов, etc) данной библиотеки, которые можно вызывать и использовать.
- Some.dll — предварительно скомпилированный бинарный файл, содержащий реализацию функционала библиотеки, т.е. непосредственно, сама динамическая библиотека. Чаще именуется просто как «dll библиотека».
- Some.lib — библиотека импорта, содержащая таблицу импорта библиотеки. Это не статическая библиотека. Несмотря на то, что расширение файла библиотеки импорта совпадает со стандартным расширением статических библиотек, путать их не стоит.
- Some.exp — библиотека экспорта, содержащая таблицу экспорта библиотеки.
Из всего списка главным являются только файлы с расширением .dll, т.е. остальных файлов может и не быть.
Количество
У одной библиотеки может быть множество файлов таких типов. Все они, обычно, рассортированы по соответствующим папкам, чтобы было легче подключать в IDE.
Вариации
Файлы dll, lib и exp различаются по платформе (ОС), архитектуре, конфигурации, etc. В одной версии библиотеки может предоставляться сразу несколько альтернативных вариаций одинаковых по функционалу файлов. E.g.:
- Для x32 (x86) и x64 архитектуры/платформы.
- Для конфигурации Release, Debug, etc. Для Debug конфигурации часто используются библиотеки с постфиксом *-d.dll, а для Release — без него.
- Для разных IDE.
- Для разных ОС. Составные файлы библиотек компилируется под каждую ОС отдельно, т.е. содержание и расширение зависит от ОС. E.g., в ОС MS Windows динамические библиотеки имеют расширение .dll, а в GNU/Linux — .so; статические в Win имеют расширение .lib, в ОС GNU/Linux — .a, соответственно.
Всё это крайне важно, всё надо учитывать при подключении библиотеки к проекту. Свойства проекта в Visual C++ могут устанавливаться отдельно для каждой конфигурации (Release, Debug) и архитектуры/платформы (x32 (x86), x64).
Подключение
Перед тем, как подключать файлы библиотеки к своей программе, надо сперва открыть необходимый проект в IDE Visual Studio: Главное меню > Файл > Открыть проект.
Заголовочные файлы (.h)
Заголовочных файлов чаще всего больше одного. Все они, обычно, находятся в папке «include» в любой библиотеке.
Каталог с заголовчными файлами (.h) библиотеки указывать здесь: Главное меню > Проект > Свойства проекта > Свойства конфигурации > C/C++ > Общие > Дополнительные каталоги включаемых файлов.
Помимо указания IDE директории расположения заголовочных файлов (.h), их также по мере необходимости надо дополнительно явно указывать в коде с помощью директивы препроцессора #include
. Необходимые заголовочные файлы подключаются в коде только там, где они нужны, т.е. где используются сущности определённые в этих файлах. Заголовочные файлы можно подключать как в файле с кодом (.cpp), так и в заголовочном файле (.h), но лучше подключать именно в заголовочном файле, а в файле кода не подключать, там подключить только свой заголовочный файл. В каждом заголовочном файле подключать требуемые заголовочные файлы так:
#include "some.h" #include "foo.h"
Файлы таблиц импорта и экспорта (.lib, .exp)
Файлы таблиц импорта и экспорта (.lib, .exp), обычно, находятся в папке «lib» в любой библиотеке.
Каталог с файлами таблиц импорта (.lib) библиотеки указывать здесь: Главное меню > Проект > Свойства проекта > Свойства конфигурации > Компоновщик > Общие > Дополнительные каталоги библиотек.
Файл таблицы импорта (.lib)
Помимо указания IDE директории расположения файлов таблиц импорта (.lib), их также для линковки надо дополнительно явно указать. Сделать это можно двумя способами:
-
- Прописать полные названия (путь, название и расширение) .lib файлов сюда: Главное меню > Проект > Свойства проекта > Свойства конфигурации > Компоновщик > Ввод > Дополнительные зависимости. Каждая библиотека в отдельной строке. Кавычки необязательны.
В итоге они будут вписаны автоматически в строку в двойных кавычках через точку с запятой (;). E.g.:"some-graphics.lib";"some-window.lib";"some-system.lib";"open-some32.lib";"some-32.lib";%(AdditionalDependencies)
или так:
"..\..\x64\Release\LinearMath.lib"
- Прописать полные названия (путь, название и расширение) .lib файлов сюда: Главное меню > Проект > Свойства проекта > Свойства конфигурации > Компоновщик > Ввод > Дополнительные зависимости. Каждая библиотека в отдельной строке. Кавычки необязательны.
- Указать каждый .lib файл эдиножды, желательно в главном/первом файле программы, с помощью директивы препроцессора
#pragma
. E.g.:#pragma comment(lib, "some.lib") #pragma comment(lib, "foo.lib")
Можно использовать сразу два способа.
Я рекомендую использовать второй вариант, когда все подключения пишутся непосредственно в коде. Так нагляднее и переносимость кода увеличивается, когда всё, что нужно написано в самом коде, а не где-то там в настройках IDE.
Файлы библиотек (.dll)
Файлы динамических библиотек (.dll), обычно, находятся в папке «bin» в любой библиотеке.
Путь к файлам динамических библиотек .dll нигде не укажешь. Файлы .dll надо класть в соответсвующие папки IDE или ОС, но легче и лучше всего положить в папку с самим исполняемым файлом программы/приложения.
Параметры конфигурации препроцессора
Также не забывайте указывать параметры конфигурации препроцессора тут: Главное меню > Проект > Свойства проекта > Свойства конфигурации > C/C++ > Препроцессор > Определения препроцессора. Параметры являются комбинированием в определённой последовательности определённых литералов. Вот некоторые из них:
- Static — статичесий (для статических библиотек — .lib в Win),
- Dynamic — динамический (для динамических библиотек — .dll в Win),
- Release — релизная версия сборки,
- Debug — отладочная версия сборки,
- MT — многопоточная, MT от слов multi thread
- MTd — multi thread, debug
- MD — многопоточный динамический (DLL)
Некоторые возможные варианты параметров:
- MT_StaticRelease
- MTd_StaticDebug
- MD_DynamicRelease
Это далеко не все возможные параметры.
Эти параметры конфигурации препроцессора должны быть обязательно одинаковыми у всех используемых в проекте библиотек, иначе будет ошибка «Error LNK2038: несоответствие значений параметров конфигурации препроцессора» в объектных (.obj) файлах.
Примечания
Пути
Пути директории указывать без конечного слеша.
Опция Компоновщик
Когда проект представляет собой библиотеку, а не исполняемый файл, то опции Компоновщик нет. Это не потому, что для проектов типа «библиотека» указывать директории подключения др. библиотек не нужно и нельзя. Несмотря на то, что опции Компоновщик нет, директории библиотек указываются не только для проектов исполняемых файлов, а также и для библиотек. В этом случае вместо Компоновщика имеется опция Библиотекарь с примерно таким же функционалом.
Библиотеки
При запуске библиотек (файлы .dll и .lib) всегда будет выскакивать окно «с ошибкой» о том, что нельзя запустить этот файл и далее следует его точный путь. Это нормально т.к. библиотеки не запускаются в отличие от исполняемых файлов (.exe).
Заключение
На самом деле, подключать сразу столько всего зачастую не нужно. Как правило, предоставляется только исходный код и всё. Приходится самостоятельно из исходников компилировать библиотеки (файлы .dll и .lib). Т.е. нужно будет указать только заголовочные файлы .h, которые являются частью исходников.
В конце не забудьте пересобрать решение, т.е. очистить и собрать заново.