Wie mache ich Qt auf den QMYSQL-Treiber aufmerksam?

8

Ich versuche, von einer Qt-Anwendung aus auf eine MySql-Datenbank zuzugreifen, bekomme aber folgenden Fehler:

%Vor%

Ich finde das sehr seltsam, weil ich libqsqlmysql.so in meinem Qt-Ordner habe. Ich habe sogar versucht, den MySql-Treiber als statisches Plugin zu kompilieren und es meiner .pro-Datei als:

hinzuzufügen %Vor%

Aber das erzeugt auch den gleichen Laufzeitfehler (es muss das Plugin gefunden haben, weil es keinen Fehler beim Kompilieren der Anwendung gibt)

Was vermisse ich? Ich möchte vermeiden, Qt aus der Quelle kompilieren zu müssen, da dies auch auf den Deploy-Rechnern reibungslos funktionieren muss.

Übrigens: Obwohl ich Linux entwickle und teste, muss ich Windows unterstützen. Wird das gleiche Problem unter Windows auftreten? Wie kann ich den MySql-Treiber sowohl unter Linux als auch unter Windows kompilieren und verknüpfen?

Die Lösung:

Nachdem ich @ Sergeys Empfehlungen gefolgt bin, habe ich einen Strace der Anwendung gemacht, der die Ausgabe nach grep umleitet, so dass ich nach 'mysql' suchen konnte und zu meiner Überraschung suchte die Anwendung nicht nach dem Plugin bei QTDIR / plugins / sqlrivers, wo ich libqsqlmysql.so hatte, war bei QTDIR / lib. Nach dem Kopieren des Plugins in den lib-Ordner funktionierte die MySql-Verbindung.

    
Raphael 18.12.2010, 18:57
quelle

7 Antworten

10

Versuchen Sie, die gemeinsam genutzte Bibliothek mit dlopen () zu öffnen und zu sehen, ob sie geladen wird und wenn nicht, was dlerror () Ihnen sagt. Ich stoße immer auf ähnliche Probleme unter Windows. LoadLibrary () / GetLastError () hat mich mehrfach gespeichert (letztes Mal wegen einer falschen Version einer libiconv / libintl DLL). Das Ausführen von LDD auf dem Plugin kann auch helfen.

Wenn dlopen () funktioniert, versuchen Sie das Plugin mit QPluginLoader zu laden. Wenn es nicht geladen wird, dann prüfe den buildkey des Plugins. Normalerweise mache ich den schmutzigen Weg, indem ich Strings auf dem Plugin abspiele und dann nach Strings wie "buildkey" oder "QT_PLUGIN_VERIFICATION_DATA" suche. Wenn Sie nur auf den Build-Schlüssel und um ihn herum schauen, können Sie eine Vorstellung davon bekommen. Zum Beispiel können Sie feststellen, dass Sie Ihr Plugin im Veröffentlichungsmodus kompiliert haben, während Ihre Anwendung im Debug-Modus kompiliert wird. In diesem Fall stimmt der Build-Schlüssel nicht überein und das Plugin wird nicht geladen. Alles im Build-Schlüssel muss mit Ihrer Konfiguration übereinstimmen. Beachten Sie, dass die Version und der Erstellungsschlüssel unterschiedlich überprüft werden: Der Erstellungsschlüssel muss genau übereinstimmen (oder mit schwarzer Magie namens QT_BUILD_KEY_COMPAT übereinstimmen), aber in der Version muss nur die Hauptversion genau übereinstimmen, die Nebenversion muss die Version von Qt sein Plugin wurde mit oder später kompiliert und der Patch-Level wird ignoriert. Wenn Ihr Plugin also mit Qt 4.x.y kompiliert wurde, wird es mit Qt-Versionen 4.z. * funktionieren, wobei z & gt; = x. Das macht eigentlich Sinn.

Wenn der Build-Schlüssel in Ordnung ist (was unwahrscheinlich ist, wenn Sie zu diesem Punkt gekommen sind), sollten Sie sich den QLibraryPrivate :: isPlugin () Quellcode ansehen, um herauszufinden, was falsch ist, aber das sieht nicht einfach aus Aufgabe für mich (obwohl das Ausführen in einem Debugger kann helfen).

Wenn QPluginLoader das Plugin lädt, prüfen Sie, ob es sich im richtigen Verzeichnis befindet und die richtigen Berechtigungen hat. Wenn Sie das Problem zu diesem Zeitpunkt noch nicht gelöst haben, sollten Sie sich den Quellcode des SQL-Moduls ansehen, der diese Plugins tatsächlich lädt. Aber es ist extrem unwahrscheinlich. Ich habe dieses Problem viele Male erlebt und es war immer entweder die Bibliothek nicht geladen oder der Build-Schlüssel nicht übereinstimmend.

Eine weitere Möglichkeit, nachdem QPluginLoader das Plugin erfolgreich geladen hat, ist die Verwendung von strace, um herauszufinden, ob das Programm zumindest versucht, die Plugin-Datei zu öffnen. Nach etwas wie "sqldrivers" oder "plugins" in der strace-Ausgabe zu suchen, sollte auch das Verzeichnis angeben, in dem Qt nach seinen Plugins und speziell nach SQL-Treibern sucht.

Aktualisieren

Ist es möglich, den Treiber als statisches Plugin zu kompilieren und sich um nichts zu kümmern? Lass es uns versuchen:

%Vor%

Es kompiliert gut und jetzt habe ich libqsqlpsql.a (release) und libqsqlpsqld.a (debug) in QTDIR / plugins / sqlrivers (es ist der richtige Ort unter Windows). Ich benutze PostgreSQL-Treiber hier, aber ich denke nicht, dass es für MySQL anders sein wird, das ich gerade nicht installiert habe. Ok, lass uns ein echtes Programm damit zusammenstellen:

%Vor%

Beachten Sie, dass ich manuell eine Verbindung zu libpq herstellen musste, da sich der Linker sonst über nicht definierte Referenzen beschweren würde. Die lustige Sache ist, qmake weiß, dass qsqlpsql in QTDIR / plugins / sqlrivers befindet und setzt Compiler und Linker-Optionen entsprechend. Es muss also immer noch am richtigen Ort sein, um zu arbeiten, nur müssen Sie sich keine Sorgen machen, dass Ihre Benutzer auf das gleiche Problem stoßen, wie es nur beim Kompilieren verwendet wird. Eine Alternative wäre, einfach LIBS+=-Lpath/to/plugin LIBS+=-lqsqlpsql anstelle von QTPLUGIN+=qsqlpsql zu verwenden, zumindest sagen die Dokumente, dass es funktionieren sollte, aber ich habe es nicht getestet.

Damit die Anwendung das Plugin tatsächlich verwenden kann, musste ich Folgendes in meine Haupteinheit (CPP-Datei) einfügen:

%Vor%

Es funktioniert! Aus dem, was ich aus den Quellen herausfinden konnte, werden der Build-Schlüssel und die Version nur geprüft, wenn ein Plugin dynamisch geladen wird (alle relevanten Dinge sind in der privaten Klasse von QLibrary, nicht einmal die von QPluginLoader). Daher kann die resultierende ausführbare Datei (oder auch nicht, abhängig von der Binärkompatibilität) sogar mit verschiedenen Versionen und Builds von Qt funktionieren, obwohl die Verwendung mit älteren Versionen möglicherweise einige Fehler verursacht, die später behoben wurden.

Beachten Sie auch, dass die Reihenfolge zum Laden von SQL-Treibern folgendermaßen lautet: Verwenden Sie den in Qt statisch verknüpften Treiber, falls verfügbar, dann suchen Sie manuell nach einem manuell registrierten Treiber mit QSqlDatabase :: registerSqlDriver () und suchen Sie nach einem statisch importierten Treiber in die Anwendung (wie oben beschrieben) und schließlich versuchen, ein freigegebenes Plugin zu laden. Wenn Sie also statisch verknüpfen, können Ihre Benutzer nicht dynamisch verknüpfte Treiber verwenden, die sie bereits haben, aber sie können statisch in Qt verknüpfte Treiber verwenden (wie in Ubuntu).

    
Sergey Tachenov 18.12.2010, 19:44
quelle
3

Ich habe zuerst QT kompiliert und dann festgestellt, dass ich auch MySQL brauche. Also ich kompilierte mysql plugin by Ausführen des folgenden Befehls im Ordner QT-DIR \ src \ plugins \ sqdrivers \ mysql.

Mysql Plugin Kompilierbefehl

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

Die Plugins werden dann im Ordner QT-DIR \ plugins \ sqldrivers erstellt. Allerdings habe ich versucht, es in meinem Code zu verwenden. Es ist mit folgendem Fehler fehlgeschlagen.

Fehler msg

QSqlDatabase: QMYSQLDriver-Treiber nicht geladen

Lösung

Nachdem ich die Pfadvariable gegoogelt und überprüft habe, habe ich gemerkt, dass der Mysql Server lib ist (C: \ Programme \ MySQL \ MySQL Server 5.5 \ lib) Verzeichnis befand sich nicht in meiner Pfadvariablen. Ich erwarte, dass die DLL in diesem Ordner zur Laufzeit vom Plugin verwendet wird. Nach dem Einbinden von Mysql Server lib in Path Variable lief alles reibungslos. Hoffe, dass diese Informationen einige Haare auf anderen Kopfhaut Programmierer sparen, wie ich einige entwurzelte. : D

    
Pratik 22.08.2011 17:12
quelle
2

Als ich das letzte Mal angeschaut habe, mussten Sie Qt von der Quelle neu erstellen und die entsprechende MySQL-Quelle einbinden.

Qt aus den Quellen zu bauen ist nicht schwer, es dauert nur eine Weile. Sie haben wahrscheinlich die erforderlichen Tools bereits.

Eine mögliche Problemumgehung besteht möglicherweise darin, stattdessen auf das Back-End über ODBC zuzugreifen.

    
Dirk Eddelbuettel 18.12.2010 18:59
quelle
2

Damit Ihre App das Plug-in zur Laufzeit abruft, muss die gemeinsam genutzte Bibliothek, die das MySQL-Plugin implementiert, in das richtige Verzeichnis gestellt werden. Der beste Weg, dieses Verzeichnis zu bestimmen, besteht darin, die Ausgabe von QCoreApplication::libraryPaths zu überprüfen. Sie können bestimmte Pfade auch erzwingen, indem Sie eine qt.conf -Datei verwenden.

Bitte beachten Sie, dass Plugins in Unterverzeichnissen innerhalb des Plug-in-Pfads platziert werden müssen und der letzte Teil des Pfadnamens (d. h. das übergeordnete Verzeichnis der gemeinsam genutzten Bibliotheken) nicht geändert werden kann. SQL-Treiber müssen in ein Verzeichnis namens sqldrivers , d. H.% Co_de%, gehen. Weitere Informationen zu Plug-in-Verzeichnissen finden Sie unter So erstellen Sie Qt-Plugins .

    
Mihai Limbășan 18.12.2010 20:49
quelle
1

Ich hatte das gleiche Problem. Ich habe viele verschiedene Python-Tools und Benutzeroberflächen installiert und damit experimentiert. Ich habe dann alles python-bezogene deinstalliert. Ich habe eine Neuinstallation von Python 3.2, PyQT 3.2 und Eric5 durchgeführt. Keine weiteren Fehler mit dem QMySQL-Treiber.

    
Tim 14.04.2011 19:01
quelle
1

Nun, ich hatte dieses Problem, und nach einer Menge Zeit, und verschiedene Tools, fand ich, dass QT (auf Windows, war nicht in der Lage, auf Linux zu testen.) lädt die "QSQLMYSQL ..", wenn angefordert, aber Vor der Laufzeit muss sich die lib-Datei ("QSQLMYSQL ..") in einem der gesuchten Pfade (QApp.libraryPaths ()) in einem Ordner namens "sqldrivers" befinden. Andernfalls ignoriert QT die Datei nur, selbst wenn sie vorhanden ist anderer Punkt innerhalb des gesuchten Pfades. Was ich tat, war, die Abhängigkeit einer Beispielanwendung zu überwachen, und als ich die "QSQLMYSQL .." DLL von "plugins \ sqldrivers \" löschte, scheiterte es, aber wenn ich einen Ordner innerhalb des APP-Ordners, genannt "sqldrivers" und platzierte das "QSQLMYSQL ..." dort, es geladen. was ich habe, ist mysql 5.5, qt 4.7.4.

Ich hoffe, dass jeder das verwenden kann, und wenn jemand mehr darüber weiß, würde ich gerne wissen, wo ich es finden kann (http://doc.qt.nokia.com/stable/sql-driver.html, ist am nächsten Sie können zu den Informationen über die Ordnerstruktur gelangen). : P

    
Kasper T 27.09.2011 21:43
quelle
0

Dies kann auch passieren, wenn Ihr QMYSQL-Plugin mit dem "falschen" mysql_client.a verknüpft ist oder es sich nicht im LD_LIBRARY_PATH befindet. Ich hatte dieses Problem unter OSX, weil mysql über Ports installiert wurde, und ich habe es mit:

behoben %Vor%     
user2996134 06.12.2013 10:39
quelle

Tags und Links