2015-07-24 4 views
7
geladen

Ich habe eine Qt dynamische lib erstellt, die Qt SQL verwendet eine SQLite-Datenbank zu öffnen, aber ich bin immer diese Fehlermeldung:Qt C++ Bibliothek in Android Eclipse-Projekt: QSQLITE Treiber nicht

QSqlDatabase: QSQLITE driver not loaded 
QSqlDatabase: available drivers: 

Die DLL funktionierte gut als Teil einer Qt-Android-Anwendung, aber ich muss es über JNI aus einer bestehenden Java-Anwendung in Eclipse entwickelt verwenden.

Dies ist der kürzeste Beispielcode, der das Problem reproduziert. Ich lade die Bibliothek von Java und rufen seine init() Methode:

System.loadLibrary("plugins_sqldrivers_libqsqlite"); 
System.loadLibrary("Qt5Sql"); 
System.loadLibrary("MyQtLib"); 
MyQtLib.init(); 

Und in der Qt-Bibliothek Ich nenne nur QSqlDatabase :: addDatabase():

JNIEXPORT void JNICALL Java_test_MyQtLib_foo(JNIEnv *, jclass) 
{ 
    // Manually create a QCoreApplication instance. 
    int argc = 1; 
    static char arg[] = ""; 
    static char *arg2 = arg; 
    app = new QCoreApplication(argc, &arg2); 
    // Try to add an SQLite db connection. 
    QSqlDatabase::addDatabase("QSQLITE"); 
} 

Da der Fehler QSQLITE driver not loaded ist, und die Qt Bibliothek arbeitete in einer Qt-Anwendung, ich nehme an, dass Qt einige Initialisierung, die ich vermisse.

Aber das hat den Fehler nicht entfernt, also muss es etwas anderes sein. Normalerweise wird die Qt-Anwendung QtApplication.java und QtActivity.java verwenden, um einige Initialisierung durchzuführen, also müssen sie etwas mehr dort tun, das ich nicht mache.

+0

könnte Ihnen helfen ... http://stackoverflow.com/questions/15944120/how-to-install-mysql-c-driver-on-windows – AngryDuck

+0

@AngryDuck Danke für den Link, aber ich konnte nicht finden alles, was für meine Frage relevant ist, außer die Fehlermeldung ist die gleiche. Dieser Typ ist auf Windows statt auf Android und sein Anwendungsszenario ist komplett anders - er lädt keine Qt shared library in ein bestehendes Eclipse android Projekt. Hattest du einen bestimmten Grund, den Link zu posten, d. H., Fehlt mir etwas? – sashoalm

Antwort

4

Schließlich ging ich in die Qt-Quellen, um zu sehen, wie das SQLITE-Plugin geladen wird (zumindest für den Desktop-Build).

Die relevante Funktion war QFactoryLoader::update(). Darin bemerkte ich, dass es alle Verzeichnisse in QCoreApplication::libraryPaths() iteriert:

QStringList paths = QCoreApplication::libraryPaths(); 
for (int i = 0; i < paths.count(); ++i) { 

Wenn einer von ihnen ein Unterverzeichnis namens „sqldrivers“ hat es in ihm geht und versucht, alle dynamischen Bibliotheken in diesem Teil laden Verzeichnis.

Ich druckte dann die Bibliothekswege in einem Testprojekt, das ich direkt von Qt Creator - qDebug() << a.libraryPaths(); lief, und ich sah diesen Pfad - /data/data/org.qtproject.example.untitled/qt-reserved-files/plugins. In diesem Verzeichnis auf meinem Android-Telefon gab es ein Unterverzeichnis namens sqldrivers, das eine einzige Datei enthielt - libqsqlite.so.

Ich habe dann die .java-Dateien, und zwar QtActivity::startApp() fügt den Bibliothekspfad:

boolean bundlingQtLibs = false; 
if (m_activityInfo.metaData.containsKey("android.app.bundle_local_qt_libs") 
    && m_activityInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { 
    localPrefix = getApplicationInfo().dataDir + "/"; 
    pluginsPrefix = localPrefix + "qt-reserved-files/"; 
    cleanOldCacheIfNecessary(localPrefix, pluginsPrefix); 
    extractBundledPluginsAndImports(pluginsPrefix); 
    bundlingQtLibs = true; 
} 

Die Lösung wird dann zu gewährleisten wäre, dass es ein sqldrivers/libqsqlite.so am Telefon irgendwo ist, und dann die übergeordneten Ordner hinzufügen von sqldrivers in den Bibliothekspfad unter Verwendung von QCoreApplication::addLibraryPath().

+0

Alter, du hast mir das Leben gerettet. Ich hatte das gleiche Problem und blieb mehrere Tage blockiert. Ihr Beitrag hilft mir viel Vielen Dank !!!! – suns9

+0

Ich blieb auch mehrere Tage blockiert. Am Ende dachte ich, wenn es mindestens einer Person hilft, lohnt es sich zu posten, wenn man bedenkt, wie viel von einem Blocker dieses Problem war. Warum hast du einige Tage gewartet, bevor du SO getroffen hast? – sashoalm

+0

Weil ich anfing, immer wieder das qt doc zu lesen, um zu versuchen, den Treibereinsatzteil zu verstehen. Aber nach Tagen des Lesens hat dies meine Situation nicht entsperrt. Ich habe auch versucht, sqlite3 in meiner App zu verwenden, aber es war auch zu schwer, es in den nativen Teil meiner App zu importieren – suns9