8

我正在尝试从 Qt 应用程序访问 MySql 数据库,但出现以下错误:

QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QSQLITE2

我觉得这很奇怪,因为我的 Qt 文件夹中有 libqsqlmysql.so。我什至尝试将 MySql 驱动程序编译为静态插件并将其添加到我的 .pro 文件中:

QTPLUGIN += qsqlmysql

但这也会产生相同的运行时错误(它一定是找到了插件,因为编译应用程序没有错误)

我错过了什么?我想避免必须从源代码编译 Qt,因为这也必须在部署机器上无缝工作。

顺便说一句:即使我在 Linux 上进行开发和测试,我也需要支持 Windows。我会在 Windows 上遇到同样的问题吗?如何在 Linux 和 Windows 中编译和链接 MySql 驱动程序?

解决方案:

在遵循@Sergey 的建议之后,我对应用程序进行了跟踪,将输出重定向到 grep,这样我就可以搜索“mysql”,令我惊讶的是,应用程序没有在我有 libqsqlmysql.so 的 QTDIR/plugins/sqldrivers 中寻找插件,它正在查看 QTDIR/lib。将插件复制到 lib 文件夹后,MySql 连接工作。

4

7 回答 7

10

尝试使用 dlopen() 打开共享库,看看它是否加载,如果没有,dlerror() 会告诉你什么。我总是在 Windows 上遇到类似的问题。LoadLibrary()/GetLastError() 多次救了我(上次是因为某些 libiconv/libintl DLL 的版本错误)。在插件上运行 ldd 也可能有所帮助。

如果 dlopen() 工作正常,请尝试使用 QPluginLoader 加载插件。如果没有加载,请检查插件的 buildkey。我通常通过在插件上运行字符串然后寻找像“buildkey”或“QT_PLUGIN_VERIFICATION_DATA”这样的字符串来做这件事。只需查看构建密钥及其周围可能会给您一个想法。例如,您可能意识到您在发布模式下编译了插件,而您的应用程序在调试模式下编译。在这种情况下,构建密钥将不匹配并且插件不会加载。构建密钥中的所有内容都必须与您的配置相匹配。请注意,版本和构建密钥的检查方式不同:构建密钥必须完全匹配(或匹配一些称为 QT_BUILD_KEY_COMPAT 的黑魔法),但在版本中只有主版本必须完全匹配,次要版本必须是编译插件时使用的 Qt 版本或更高版本,并且忽略补丁级别。因此,如果您的插件是使用 Qt 4.xy 编译的,那么它将适用于 z>=x 的 Qt 版本 4.z.*。这实际上是有道理的。

如果构建密钥看起来不错(如果您到了这一点,这不太可能),您可能希望查看 QLibraryPrivate::isPlugin() 源代码以找出问题所在,但这对我来说似乎不是一件容易的事(尽管在调试器中运行它可能会有所帮助)。

如果 QPluginLoader 确实加载了插件,请检查它是否在正确的目录中并且具有正确的权限。如果此时您仍然没有解决问题,那么是时候查看实际加载这些插件的 SQL 模块源代码了。但这极不可能。我多次遇到这个问题,总是库未加载或构建密钥不匹配。

QPluginLoader 成功加载插件后的另一种方法是使用 strace 来确定程序是否至少尝试打开插件文件。在 strace 输出中搜索“sqldrivers”或“plugins”之类的内容也应该放弃 Qt 搜索其插件的目录,特别是 SQL 驱动程序。

更新

是否可以将驱动程序编译为静态插件并且不用担心任何事情?咱们试试吧:

d:\Qt4\src\plugins\sqldrivers\psql>qmake CONFIG+=static LIBS+=-Ld:/programs/Post
greSQL/lib INCLUDEPATH+=d:/programs/PostgreSQL/include
d:\Qt4\src\plugins\sqldrivers\psql>make

它编译得很好,现在我在 QTDIR/plugins/sqldrivers 中得到了 libqsqlpsql.a(发布)和 libqsqlpsqld.a(调试)(这Windows 上的正确位置)。我在这里使用的是 PostgreSQL 驱动程序,但我认为对于我没有安装的 MySQL 来说它不会有任何不同。好的,让我们用它编译一些真正的程序:

d:\alqualos\pr\archserv>qmake QTPLUGIN+=qsqlpsql PREFIX=d:/alqualos LIBS+=-Ld:/g
nu/lib INCLUDEPATH+=d:/gnu/include LIBS+=-Ld:/programs/PostgreSQL/lib LIBS+=-lpq

请注意,我必须手动链接到 libpq,否则链接器会抱怨未定义的引用。有趣的是,qmake 知道 qsqlpsql 位于 QTDIR/plugins/sqldrivers 并相应地设置编译器和链接器选项。所以它仍然需要在正确的地方工作,只是你不必担心你的用户会遇到同样的问题,因为它只在编译期间使用。另一种方法是只使用LIBS+=-Lpath/to/plugin LIBS+=-lqsqlpsql而不是QTPLUGIN+=qsqlpsql,至少文档说它应该可以工作,但我还没有测试过。

为了让应用程序真正使用插件,我必须在我的主单元(CPP 文件)中添加以下内容:

#include <QtPlugin>
Q_IMPORT_PLUGIN(qsqlpsql)

有用!此外,根据我从源代码中了解到的信息,只有在动态加载插件时才会检查构建密钥和版本(所有相关内容都在 QLibrary 的私有类中,甚至没有 QPluginLoader 的)。因此,生成的可执行文件可能(或可能不会,取决于二进制兼容性)即使在不同版本和 Qt 构建下也能工作,尽管将它与旧版本一起使用可能会触发一些稍后修复的错误。

另外值得注意的是,加载 SQL 驱动的顺序是这样的:如果可用,使用静态链接到 Qt 中的驱动,然后查找使用 QSqlDatabase::registerSqlDriver() 手动注册的驱动,然后查找静态导入到应用程序中的驱动(如上所述的方式),最后尝试加载一个共享插件。因此,当您静态链接时,您的用户将无法使用他们可能已经拥有的动态链接驱动程序,但能够使用静态链接到 Qt 的驱动程序(如在 Ubuntu 中)。

于 2010-12-18T19:44:00.357 回答
3

我先编译了QT,然后意识到我也需要mysql。所以我通过在 QT-DIR\src\plugins\sqldrivers\mysql 文件夹中执行以下命令来编译 mysql 插件。

Mysql插件编译命令

qmake "INCLUDEPATH+=$$quote(C:\Program Files\MySQL\MySQL Server 5.5\include)" "LIBS+=$$quote(C:\Program Files\MySQL\MySQL Server 5.5\lib\libmysql.lib)" mysql .pro

然后在文件夹 QT-DIR\plugins\sqldrivers 中创建插件。但是,当我尝试在我的代码中使用它时。它因以下错误而失败。

错误信息

QSqlDatabase:未加载 QMYSQLDriver 驱动程序

解决方案

经过一番谷歌搜索和检查 Path 变量后,我意识到 Mysql 服务器 lib(C:\Program Files\MySQL\MySQL Server 5.5\lib)目录不在我的 Path 变量中。我希望插件在运行时使用此文件夹中的 dll。在 Path 变量中包含 Mysql 服务器库后,一切正常。希望这些信息能在其他程序员的头皮上节省一些头发,因为我连根拔起不少。:D

于 2011-08-22T17:12:14.847 回答
2

上次我看到这个时,您需要从源代码重建 Qt 并包含适当的 MySQL 源代码。

从源代码构建 Qt 并不难,只是需要一段时间。您可能已经拥有所需的工具。

一种可能的解决方法可能是改为通过 ODBC 访问后端。

于 2010-12-18T18:59:25.570 回答
2

为了让您的应用程序在运行时获取插件,实现 MySQL 插件的共享库需要放置在正确的目录中。确定该目录的最佳方法是检查QCoreApplication::libraryPaths. 您还可以通过使用qt.conf文件来强制使用特定路径。

请注意插件必须放在插件路径内的子目录中,不能更改路径名的最后部分(即共享库的父目录)。SQL 驱动程序需要进入一个名为sqldriversie的目录<pluginpath>/sqldrivers。有关插件目录的更多详细信息,请参阅如何创建 Qt 插件

于 2010-12-18T20:49:32.843 回答
1

我也遇到了同样的问题。我一直在安装和试验许多不同的 Python 工具和 UI。然后我卸载了所有与 python 相关的东西。我全新安装了 Python 3.2、PyQT 3.2 和 Eric5。QMySQL 驱动程序不再出现错误。

于 2011-04-14T19:01:04.327 回答
1

好吧,我遇到了这个问题,经过很多时间和不同的工具,我发现 QT(在 Windows 上,无法在 Linux 上测试。)在请求时加载“QSQLMYSQL ..”,但在运行之前lib ("QSQLMYSQL..") 文件必须位于名为 "sqldrivers" 的文件夹内的搜索路径之一 (QApp.libraryPaths()) 上。否则 QT 将忽略该文件,即使它位于内部的其他位置搜索到的路径。我所做的是监视示例应用程序的依赖关系,当我从“plugins\sqldrivers\”中删除“QSQLMYSQL..”dll 时它失败了,但是当我在应用程序文件夹中创建一个名为“sqldrivers”的文件夹时,将“QSQLMYSQL ...”放在那里,它加载了。我拥有的是 mysql 5.5,qt 4.7.4。

希望任何人都可以使用它,如果有人对此了解更多,我想知道在哪里可以找到它(http://doc.qt.nokia.com/stable/sql-driver.html,是你能得到的最接近的到有关文件夹结构的信息)。:P

于 2011-09-27T21:43:57.373 回答
0

如果您的 QMYSQL 插件链接到“错误的”mysql_client.a 或者它不在 LD_LIBRARY_PATH 中,也可能会发生这种情况。我在 OSX 上遇到了这个问题,因为 mysql 是通过端口安装的,我用以下方法修复了它:

install_name_tool -change libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient_r.18.dylib libqsqlmysql.dylib
于 2013-12-06T10:39:00.853 回答