如何让Qt知道QMYSQL驱动程序

时间:2010-12-18 18:57:26

标签: qt qtsql

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

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

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

QTPLUGIN += qsqlmysql

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

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

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

解决方案:

在关注@ Sergey的推荐之后,我做了一个应用程序,将输出重定向到grep,所以我可以搜索'mysql',我惊讶的是应用程序不是在QTDIR上寻找插件/ plugins / sqldrivers我有libqsqlmysql.so,查看QTDIR / lib。将插件复制到lib文件夹后,MySql连接正常工作。

7 个答案:

答案 0 :(得分: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.x.y编译的,那么它将适用于Qt版本4.z. *,其中z> = x。这实际上是有道理的。

如果构建键看起来没问题(如果你到了这一点就不太可能),你可能希望查看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中)。

答案 1 :(得分:3)

我首先编译了QT然后意识到我也需要mysql。所以我编译了mysql插件 在QT-DIR \ src \ plugins \ sqldrivers \ 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 server lib之后一切顺利。希望这些信息可以节省其他程序员的头发,因为我连根拔起了一些。 :d

答案 2 :(得分:2)

上次我看到你需要从源代码重建Qt并包含相应的MySQL源代码。

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

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

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

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

答案 6 :(得分: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