Как подключить dll в qt

Обновлено: 03.07.2024

Предположим, у меня есть папка с моей программой, а также еще одна папка с внешней библиотекой.

В моем случае я хочу загрузить lib.dll из моей основной программы myprog.exe , Проблема в том, что lib.dll связан с sublib.dll ,

Поэтому я пытаюсь сделать это следующим образом:

невозможно загрузить библиотеку lib.dll указанный модуль не найден

Если я поставлю оба lib.dll а также sublib.dll внутри bin каталог работает без ошибок. Но это не я хочу сделать.

но это не работает
Насколько я понимаю QCoreApplication::addLibraryPath() задает путь для программы Qt, а не для всей системы. Итак, в этом случае, lib.dll все еще не могу найти sublib.dll хотя он находится в том же каталоге.

Решение

Это проблема Windows. DLL будет просматриваться в текущем каталоге процесса, а затем в системном PATH. Код, который содержится в некоторых C:\etc\lib.dll ведет себя в своем собственном процессе, и если только очень специфическая реализованная логика не будет вести себя в соответствии с системным правилом.

Пожалуйста, обратитесь к статье MSDN Порядок поиска в библиотеке динамических ссылок для деталей. Если исходный код для этого lib.dll доступен, имеет смысл изучить LoadLibrary вызов. Если не указан конкретный путь, тогда:

Другие решения

Ничто не мешает вам явно предварительно загрузить библиотеки, которые lib.dll зависит от. После предварительной загрузки они готовы к использованию любой библиотекой, которую вы впоследствии откроете. В конце концов, вы знаете, где они находятся, поэтому их легко перебрать и попытаться загрузить. Из-за возможных зависимостей между этими библиотеками, вы должны продолжать загружать их до тех пор, пока больше не будет прогресса:

Это либо то, либо использование библиотеки PE по вашему выбору для самостоятельного построения дерева зависимостей и открытия только необходимых библиотек в порядке зависимости.

Примечание: вы не являетесь владельцем C:\Windows и вы никогда не должны писать что-либо там (ни в какой подпапке) в каком-либо современном установщике.

Это руководство иллюстрирует разные подходы к созданию и применению пользовательских библиотек в приложении на Windows. Первая часть объясняет, как создать совместно используемую библиотеку и как присоединить ее к приложению. Вторая часть - о создании и использовании статической библиотеки.

Создание разделяемой библиотеки

При создании совместно используемой библиотеки, которую вы бы хотели присоединить, необходимо удостовериться, что символы, которые будут использованы за пределами библиотеки, будут должным образом экспортироваться после создания библиотеки. Впоследствии они будут импортированы при присоединении. Это может быть сделано с помощью Q_DECL_EXPORT и Q_DECL_IMPORT как показано в следующем примере:

  1. include <QtGui>
  1. if defined TEST
  2. define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
  3. else
  4. define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
  5. endif

test.pro TEMPLATE = lib

SOURCES += test.cpp HEADERS += test.h DEFINES += TEST

Присоединение разделяемой библиотеки к приложению

Чтобы использовать разделяемую библиотеку в приложении, вы можете включить ее заголовок в ваш код и использовать доступные методы. Скомпилируйте и соберите с.lib файл. Во время выполнения будет загружена dll, у которой имеется реализация.

Для успешной сборки, в файле .pro необходимо сообщить приложению, где найти заголовки и библиотеки. INCLUDEPATH должен указывать на каталог, где находятся заголовки, и LIBS переменная должна указывать на каталог с .lib файлом. Кроме того, необходимо удостовериться, что .dll будет находиться в указанном месте или помещена в каталог приложения или путь к ней описан в переменной PATH.

loadTestLib.pro TEMPLATE = app TARGET = DEPENDPATH += . ../testLib INCLUDEPATH += ../testLib LIBS += -L../testLib/debug -ltestLib

int main(int argc, char *argv[])

Использование QLibrary, для загрузки разделяемых библиотек

QLibrary может использоваться для загрузки разделяемых библиотек в момент выполнения. В этом случае достаточно иметь доступ только к .dll, доступ к заголовкам и .lib файлу(ам) не требуется.

Следующий пример показывает, как установить библиотеку для использования с QLibrary. Для разрешения имен функций, они должны быть экспортированы из библиотеки как C функции (т.е. без искажения имени). Это означает, что функции должны быть обернуты в блок extern "C", в случае если библиотека скомпилирована компилятором C.

Вот как делается это на Windows, также необходимо явно экспортировать функцию для использования DLL Q_DECL_EXPORT и Q_DECL_IMPORT

qlibraryLibrary.pro TEMPLATE = lib HEADERS += widget.h SOURCES += widget.cpp DEFINES += TEST

  1. include <QtGui>
  1. if defined TEST
  2. define TEST_COMMON_DLLSPEC Q_DECL_EXPORT
  3. else
  4. define TEST_COMMON_DLLSPEC Q_DECL_IMPORT
  5. endif

extern "C" TEST_COMMON_DLLSPEC QWidget* createWidget1();

Загрузка библиотеки, используя QLibrary

Чтобы загрузить библиотеку, используя QLibrary, можете просто передать .dll в конструктор QLibrary. Удостоверьтесь, что .dll доступна в каталоге приложения или в переменной PATH. Для того чтобы воспользоваться функциями библиотеки в приложении, вы должны разрешить их использование QLibrary::resolve().

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

int main(int argc, charargv)

Создание статической библиотеки

При создании статической библиотеки необходимо определить опцию staticlib CONFIG в .pro файле. В отличие от примера разделяемой библиотеки, в .h файле не требуется устанавливать никаких специальных символов для экспорта и импорта, потому как библиотека будет встроена в приложение, например:

test.pro TEMPLATE = lib CONFIG+= staticlib

HEADERS += test.h SOURCES += test.cpp

Использование статической библиотеки в приложении

Подобно тому, как мы сделали это при загрузке разделяемой библиотеки, необходимо описать INCLUDEPATH, чтобы указать на каталог, где установлены заголовки и LIBS переменную, чтобы указать на .lib файл, например:

useStaticLib.pro TEMPLATE = app TARGET = CONFIG+= console

SOURCES += main.cpp INCLUDEPATH += ../staticLibrary LIBS+= -L../staticLibrary/debug -lstaticLibrary

int main(int argc, char *argv[])

Какой подход выбрать

Принятие решения о том, какой подход выбрать, зависит от Ваших потребностей.

При создании разделяемой библиотеки потребуется установить ее в целевой системе вместе с приложением. Преимущество: приложения собранные на разделяемых библиотеках, маленькие. Это независит от того, что используется для загрузки .dll, QLibrary или просто стандартное подключение. Важно, имеете ли вы доступ к заголовочным и .lib файлам или нет. Если доступа не имеете, тогда QLibrary -ваш выбор. Недостаток в том, что при отсутствии разделяемой библиотеки в системе приложение работать не будет.

Статическое подключение позволяет создать автономно исполняемую программу. Преимущество состоит в том, что для работы программы вам необходимо будет установить только несколько файлов. Недостаток в том, что исполняемые программы большие.

Белый и Пушистый

Репутация: нет
Всего: 16

Подскажите пожалуйста как подключить к проекту на Qt библиотеку dll?

Репутация: 15
Всего: 8

Добавлено через 1 минуту и 28 секунд
А если пишешь в MSVS, то там в свойствах проекта указываешь *.lib файл библиотеки, которую нужно линковать

Репутация: 4
Всего: 5

Если честно не совсем понятно что значит подключить dll библиотеку, есть такой замечательный класс для вызова функций из длл

вот пример из ассистента

С уважением,
мастер конфетного цеха!

Белый и Пушистый

Репутация: нет
Всего: 16

ecspertiza, я создал проект в QCreator который у них называется "Библиотека С++". Так как вот теперь мне воспользоваться этой библиотекой?

Добавлено через 9 минут и 31 секунду
В проекте "библиотека С++" объявляются какие-то глобальные штуки:

Как с этим работать?

Репутация: 4
Всего: 5

Я так понимаю, что ты хочешь работать с классом SmartFlowLib ?

С уважением,
мастер конфетного цеха!

Репутация: 24
Всего: 196

Elfet, ты в начале темы спрашивал, как подключить DLL к проекту. Ответа два:
1. Если нужна жесткая привязка к DLL (т.е. без нее нельзя запускать), то ответ дал Acer
2. Если нужна опциональная возможность загрузки (типа плагина), то ответ дал ecspertiza.
3. Если тебе нужно написать плагин, то в документации Qt есть отдельная тема по этому поводу.

Белый и Пушистый

Репутация: нет
Всего: 16

bsa, мне нужна жёсткая привязка. Я написал LIBS += . однако не могу понять как воспользоваться теперь моим классом (SmartFlowLob)

ecspertiza, ооо! спасибо то что нужно! )

Репутация: 4
Всего: 5

С уважением,
мастер конфетного цеха!

Белый и Пушистый

Репутация: нет
Всего: 16

Белый и Пушистый

Репутация: нет
Всего: 16

А так и должно быть, что подключая к проекту библиотеку:

Я должен подключать так же теже библиотеки которые используются в ней:

Получается я в самой библиотеке (SmartFlowLib) подключаю libboost_serialization-mgw34-s-1_40.lib,
и в самом приложении, которое подключает SmartFlowLib подключаю libboost_serialization-mgw34-s-1_40.lib.

Так и должно быть?

Репутация: 4
Всего: 5

Я так думаю что скорее всего да, так и должно быть я просто из одной либы другу не подключал, но если проект для сборки этого требует, то скорее всего так и должно быть

С уважением,
мастер конфетного цеха!

Репутация: 1
Всего: 14

Elfet, по идее это должно быть верным только для статических библиотек.

Белый и Пушистый

Репутация: нет
Всего: 16

korbian, видимо я статическую библиотеку сделал? Нужно её динамической сделать?

Репутация: 1
Всего: 14


все зависит от дизайна твоего продукта.
если предполагается ее использование более чем в одном программном модуле в пределах системы, то логично сделать библиотеку динамически подключаемой.

Белый и Пушистый

Репутация: нет
Всего: 16

korbian, да, я для библиотеки хочу сделать два интерфейса - графический и из командной строки.
Как сделать такую библиотеку?

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

[ Время генерации скрипта: 0.1496 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Как добавить внешнюю библиотеку в проект, построенный Qt Creator RC1 (версия 0.9.2)? Например, функция win32 EnumProcesses() требует Psapi.lib для добавления в проект для сборки.

правильный способ сделать это так:

таким образом, он будет работать на всех платформах, поддерживаемых Qt. Идея заключается в том, что вы должны отделить каталог от имени библиотеки (без расширения и без префикса "lib"). Конечно, если вы включаете конкретный lib для Windows, это действительно не имеет значения.

Если вы хотите сохранить свои файлы lib в каталоге проекта, вы можете ссылаться на них с помощью $$_PRO_FILE_PWD_ переменной, например:

вы используете qmake проектов? Если это так, вы можете добавить внешнюю библиотеку с помощью LIBS переменной. Например:

не будет работать, потому что вы используете пробелы в программные файлы. В этом случае вам нужно добавить кавычки, поэтому результат будет выглядеть так:LIBS += "C:\Program Files\OpenCV\lib". Я рекомендую размещать библиотеки в местах без пробелов; -)

ошибка, которую вы имеете в виду, связана с отсутствием дополнительного пути включения. Попробуйте добавить его с помощью: INCLUDEPATH += C:\path\to\include\files\ Надеюсь, это сработает. С уважением.

и добавить несколько файлов библиотеки вы можете написать, как показано ниже:

INCLUDEPATH *= E:/DebugLibrary/VTK E:/DebugLibrary/VTK/Common E:/DebugLibrary/VTK/Filtering E:/DebugLibrary/VTK/GenericFiltering E:/DebugLibrary/VTK/Graphics E:/DebugLibrary/VTK/GUISupport/Qt E:/DebugLibrary/VTK/Hybrid E:/DebugLibrary/VTK/Imaging E:/DebugLibrary/VTK/IO E:/DebugLibrary/VTK/Parallel E:/DebugLibrary/VTK/Rendering E:/DebugLibrary/VTK/Utilities E:/DebugLibrary/VTK/VolumeRendering E:/DebugLibrary/VTK/Widgets E:/DebugLibrary/VTK/Wrapping

LIBS * = - LE: / DebugLibrary / VTKBin/bin / release -lvtkCommon -lvtksys -lQVTK-lvtkWidgets-lvtkRendering-lvtkGraphics-lvtkImaging-lvtkIO-lvtkFiltering-lvtkDICOMParser-lvtkpng-lvtktiff-lvtkzlib-lvtkjpeg-lvtkexpat-lvtkNetCDF-lvtkexoIIc-lvtkftgl-lvtkfreetype-lvtkHybrid-lvtkVolumeRendering-lvtkfreetype lqvtkwidgetplugin-lvtkgenericfiltering

Если вы хотите развернуть свое приложение на машинах клиентов, а не использовать свое приложение только самостоятельно, мы обнаружим, что LIBS+= -Lxxx -lyyy метод может привести к путанице, если нет проблем.

мы разрабатываем приложения для Linux, Mac и Windows, используя Qt. Мы грузим полные, отдельно стоящие применения. Так что все несистемные библиотеки должны быть включены в пакет развертывания. Мы хотим, чтобы наши клиенты могли запускать приложение с одного USB-накопителя для всех ОС. По причинам из совместимости платформы USB-накопитель должен быть отформатирован как FAT32, который не поддерживает символические ссылки (Linux).

мы нашли LIBS+= -Lxxx -lyyy идиома слишком много "черного ящика":

мы точно не знаем, что такое путь к файлу (статической или динамической) библиотеки, найденной компоновщиком. Это неудобно. Наш Mac linker регулярно находил библиотеки, отличные от тех, которые мы думали, что должны использоваться. Это произошло несколько раз с библиотеками OpenSSL где компоновщик Mac нашел и использовал свою собственную - более старую, несовместимую - версию OpenSSL, а не нашу запрошенную версию.

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

мы хотим видеть от имя библиотеки, связываем ли мы статическую или динамическую библиотеку.

поэтому для нашего конкретного случая мы используем только абсолютные filepaths и проверьте, существуют ли они. Мы удаляем все ссылки.

Сначала мы узнаем, какую операционную систему мы используем, и помещаем это в переменную CONFIG. И, например, для Linux 64bit, затем:

все зависимости могут быть скопированы в пакет развертывания, поскольку мы знаем их пути к файлам.

Я хотел бы добавить для полноты, что вы также можете добавить только путь к библиотеке, где он будет искать зависимую библиотеку (на которую может не быть прямой ссылки в вашем коде, но библиотека, которую вы используете, может понадобиться).

для сравнения, это будет соответствовать тому, что делает среда LIBPATH, но ее вид неясен в Qt Creator и не хорошо документирован.

путь, которым я обошел это, следующий:

по сути, если вы не укажите фактическое имя библиотеки, он добавляет путь к тому, где он будет искать зависимые библиотеки. Разница в синтаксисе невелика, но это очень полезно, чтобы указать только путь, где искать зависимые библиотеки. Иногда это просто боль, чтобы предоставить каждому пути отдельную библиотеку, где вы знаете, что все они находятся в определенной папке, и Qt Creator подберет их.

Читайте также: