Android Eclipse项目中的Qt C ++库:未加载QSQLITE驱动程序

时间:2015-07-24 09:44:36

标签: android c++ eclipse qt

我已经创建了一个使用Qt SQL打开SQLite数据库的Qt动态库,但是我收到了这个错误:

getStuff()

DLL作为Qt Android应用程序的一部分工作正常,但是我需要通过JNI从Eclipse中开发的现有Java应用程序中使用它。

这是再现问题的最短示例代码。我从Java加载库并调用其QSqlDatabase: QSQLITE driver not loaded QSqlDatabase: available drivers: 方法:

init()

在Qt库中我只调用QSqlDatabase :: addDatabase():

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

由于错误是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"); } ,并且Qt库在Qt应用程序中运行,我假设Qt正在进行一些我缺少的初始化。

但是这并没有消除错误,所以它必须是别的东西。通常,Qt应用程序将使用QtApplication.javaQtActivity.java来执行一些初始化,因此他们必须在那里做更多我不做的事情。

1 个答案:

答案 0 :(得分:4)

最终我进入了Qt源代码,看看SQLITE插件是如何加载的(至少对于桌面版本来说)。

相关功能是QFactoryLoader::update()。在其中我注意到它迭代QCoreApplication::libraryPaths()中的所有目录:

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

如果它们中的任何一个有一个名为“sqldrivers”的子目录,它会进入它并尝试加载该子目录中的所有动态库。

然后我在Qt Creator直接运行的测试项目中打印出库路径 - qDebug() << a.libraryPaths();,我看到了这条路径 - /data/data/org.qtproject.example.untitled/qt-reserved-files/plugins。在我的Android手机上的这个目录中,有一个名为sqldrivers的子目录,其中包含一个文件 - libqsqlite.so

然后我检查了.java文件,确实QtActivity::startApp()添加了库路径:

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;
}

然后解决方案是确保手机上某处有sqldrivers/libqsqlite.so,然后使用sqldriversQCoreApplication::addLibraryPath()的父文件夹添加到库路径。