Дано
ОС Windows 7 или 10 x64
Qt5.5.1 (mingw) (x86) или новее
PostgreSQL 10 или новее
Задача
Заставить разработанное на Qt приложение запускаться на машине без установленного Qt и PostgreSQL и подключаться к СУБД PostgreSQL.
ОС Windows 7 или 10 x64
Qt5.5.1 (mingw) (x86) или новее
PostgreSQL 10 или новее
Задача
Заставить разработанное на Qt приложение запускаться на машине без установленного Qt и PostgreSQL и подключаться к СУБД PostgreSQL.
Проблема
При вызове QSqlDatabase::addDatabse("QPSQL") программа пишет:
QSqlDatabase: QPSQL driver not loadedQSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7
либо вовсе:
QSqlDatabase: QPSQL driver not loadedQSqlDatabase: available drivers:
Анализ
Как в общих чертах происходит работа с БД в Qt:Функция QSqlDatabase::addDatabse живет в Qt5Sql.dll, и при вызове пытается динамически подгрузить qsqlpsql.dll, которая тянет за собой кучу других dll, часть из которых живет в составе PostgreSQL.
Разберемся, как решать эту и подобные проблемы, связанные с dll.
Принципиально существует два способа связывания dll и exe-файлов: явное и неявное. При загрузке SQL-драйверов Qt задействованы оба способа.
Сначала при запуске exe-файла происходит поиск и загрузка требуемых dll-библиотек, в т.ч. Qt5Sql.dll. Если какие-то библиотеки не найдены, то при запуске программы Windows сообщит об этом.
Принципиально существует два способа связывания dll и exe-файлов: явное и неявное. При загрузке SQL-драйверов Qt задействованы оба способа.
Сначала при запуске exe-файла происходит поиск и загрузка требуемых dll-библиотек, в т.ч. Qt5Sql.dll. Если какие-то библиотеки не найдены, то при запуске программы Windows сообщит об этом.
В процессе работы программы при вызове QSqlDatabase::addDatabse делается динамический поиск dll-файлов SQL-драйверов в определенных каталогах. Для драйвера QPSQL должна быть найдена библиотека qsqlpsql.dll, после чего выполняется попытка ее загрузки.
Для этого загружаются другие неявно связанные с ней dll-библиотеки вместе со своими зависимостями. Если всё дерево необходимых dll-библиотек найдено, то qsqlpsql.dll будет успешно загружена и Qt сможет использовать этот драйвер.
Но сложность в том, что при отсутствии какой-либо библиотеки Windows не выдаст красивого сообщения об этом и придется разбираться другими способами.
Разбираемся
Нам надо выяснить, какие dll-библиотеки требуются для работы программы и куда их нужно положить.
Для этого достаточно в общих чертах представлять, как Windows ищет dll, а именно, что сначала производится поиск в каталоге exe-файла, а в конце - по путям, указанным в переменной окружения PATH. PATH удобно использовать на машине разработчика, но этот вариант рассматривать не будем т.к. это не соответствует изначальной задаче.
Также надо знать, в каких каталогах QSqlDatabase::addDatabse ищет драйверы SQL. Существуют способы указать Qt альтернативные пути, где искать плагины (в т.ч. SQL), но не будем заниматься и этим.
Исследуем
Используем Прекрасную программы DependencyWalker, которая показывает дерево зависимостей dll и exe-файлов.
Сначала открываем с помощью неё исполняемый файл программы и смотрим, какие dll-библиотеки должны быть доступны, ищем их в каталоге установки Qt и компилятора и кладем рядом с исполняемым файлом. Теперь программа должна запускаться и доходить до вызова QSqlDatabase::addDatabse.
Чтобы увидеть, где Qt ищет SQL-драйверы, добавляем переменную окружения QT_PLUGIN_PATH = 1 (например, в настройках параметров запуска приложения в QtCreator), запускаем программу и изучаем ее вывод. Кроме прочего должны быть примерно такие строки:
QFactoryLoader::QFactoryLoader() checking directory path "C:/Qt/Qt5.5.1/5.5/mingw492_32/plugins/sqldrivers"
...
QFactoryLoader::QFactoryLoader() checking directory path "C:/projects/build-foobar-Desktop-Release/release/sqldrivers"
Из них становится ясно, что по умолчанию Qt ищет SQL-драйверы в каталоге установки и в подкаталоге sqldrivers рядом с exe-файлом. Поэтому находим qsqlpsql.dll в каталоге установки Qt (примерно в C:\Qt\5.5.1\mingw491_32\bin\plugins\sqldrivers) и копируем в подкаталог sqldrivers рядом с exe-файлом.
Если все сделано верно, то после вызова QSqlDatabase::addDatabse должно вывестись:
QSqlDatabase: available drivers: QPSQL QPSQL7
Если не удалось, то попробовать положить qsqlpsql.dll в plugins/sqldrivers.
Далее с помощью DependencyWalker исследуем зависимости qsqlpsql.dll.
Кроме зависимостей от библиотек Qt и компилятора, будет зависимость от libpq.dll.
Проще всего взять libpq.dll из каталога установки PostgreSQL (примерно в C:\Program Files (x86)\PostgreSQL\10\bin). Здесь есть две важнейшие особенности:
1) разрядность libpq.dll должна совпадать с разрядностью приложения. Под Windows стандартный SDK Qt5 с официального сайта 32-разрядный. т.е. необходима 32-разрядная версия libpq.dll, которую можно взять из x86-версии PostgreSQL. Это не влияет на разрядность сервера PostgreSQL, к которому будет подключаться приложение;
2) libpq.dll необходимо располагать рядом с exe-файлом, а не рядом с qsqlpsql.dll. Все остальные dll, от которых зависит libpq.dll, необходимо класть также рядом с exe-файлом приложения.
Теперь все тем же DependencyWalker исследуем зависимости libpq.dll в каталоге установки PostgreSQL.
В зависимости от версии PostgreSQL у libpq.dll могут быть разные dll-зависимости. Находим их все в каталоге установки PostgreSQL и копируем рядом с exe-файлом. Не забываем пройтись по всем зависимостям всех добавляемых dll.
Сравниваем
Из установленного PostgreSQL 9.4 нужно позаимствовать следующие библиотеки:
libpq.dll
ssleay32.dll
libeay32.dll
libintl-8.dll
libiconv-2.dll
libpq.dll
ssleay32.dll
libeay32.dll
libintl-8.dll
libiconv-2.dll
Для PostgreSQL 10 набор уже другой:
libpq.dll
libssl-1_1.dll
libcrypto-1_1.dll
libintl-8.dll
libiconv-2.dll
Более новые версии PostgreSQL выпускаются только в редакции x64, поэтому для получения x86-версии libpq.dll и других библиотек, возможно, придется собирать их из исходников самостоятельно (я не пробовал).
Что еще
возможно, Вам, как и мне, потребуется откуда-то добыть msvcr120.dll (или что-то вроде того в новых версиях Windows и PostgreSQL) и тоже бросить рядом с exe-файлом.
Итого
У меня получилась следующая структура каталога простой консольной программы, выполняющей загрузку драйвера БД:
Архив c примером на гуглодиске
Что еще
возможно, Вам, как и мне, потребуется откуда-то добыть msvcr120.dll (или что-то вроде того в новых версиях Windows и PostgreSQL) и тоже бросить рядом с exe-файлом.
Итого
У меня получилась следующая структура каталога простой консольной программы, выполняющей загрузку драйвера БД:
qpsqltest.exe
sqldrivers/qsqlpsql.dll
Qt5Core.dll
Qt5Sql.dll
libpq.dll
libssl-1_1.dll
libcrypto-1_1.dll
libintl-8.dll
libiconv-2.dll
libwinpthread-1.dll
libstdc++-6.dll
libgcc_s_dw2-1.dll
msvcr120.dll
Архив c примером на гуглодиске
Спасибо большое!
ОтветитьУдалитьУ меня была ошибка QSqlDatabase: QPSQL driver not loaded.
Всё что требовалось для ее решение это скачать ваш набор dll и положить их рядом с exe файлом. И проблема решена.
Использую Qt 5.8 к слову.
Thank you so much!
ОтветитьУдалитьБлагодарствую!
ОтветитьУдалитьСпасибо!
ОтветитьУдалитьПомогло!
Спасибо помогло!!))
ОтветитьУдалитьПомогло
ОтветитьУдалитьустановил библиотеки и... вода пошла
ОтветитьУдалитьСпасибо
Спс.Помогло.
ОтветитьУдалитьАрхив не открывается, можно ли вас попросить заново его на диск залить?
ОтветитьУдалитьОбновил заметку
Удалить