我正在尝试为我正在使用Qt的SQLite数据库创建一个自定义函数。我找到了有关如何创建函数的信息,它似乎在x86系统上正常工作。
相反,似乎在ARM设备上出现了段错误。这是我写的代码:
static bool createSQLiteFunctions(const QSqlDatabase& db)
{
// Get handle to the driver and check it is both valid and refers to SQLite3.
QVariant v = db.driver()->handle();
if (!v.isValid() || qstrcmp(v.typeName(), "sqlite3*") != 0) {
LOG_WARNING("Cannot get a sqlite3 handle to the driver.");
return false;
}
// Create a handler and attach functions.
sqlite3* handler = *static_cast<sqlite3**>(v.data());
if (!handler) {
LOG_WARNING("Cannot get a sqlite3 handler.");
return false;
}
// Check validity of the state.
if (!db.isValid()) {
LOG_ERROR("Cannot create SQLite custom functions: db object is not valid.");
return false;
}
if (!db.isOpen()) {
LOG_ERROR("Cannot create SQLite custom functions: db object is not open.");
return false;
}
if (sqlite3_create_function(handler, "_deleteFile", 1, SQLITE_ANY, 0, &_sqlite3DeleteFile, 0, 0))
LOG_ERROR("Cannot create SQLite functions: sqlite3_create_function failed.");
return true;
}
db对象被实例化为另一个对象的成员,该对象在构造函数中调用此函数,其中建立了与db的连接(可以同时创建多个实例,但是使用线程安全选项编译sqlite3) 。 似乎没有打印错误日志,但sqlite3_create_function函数给出了段错误。如果我删除对createSQLiteFunctions的调用,一切正常。 知道为什么结果是段错误吗? 谢谢!
答案 0 :(得分:1)
如果它在ARM上失败,可能需要对编译(你使用的是什么sqlite3)或者回调函数本身(_sqlite3DeleteFile)做些什么。它是如何定义的,位于/链接的位置。根据ARM(您使用的是ARM),处理器可能非常挑剔并且对齐。 检查你的地图文件,也许是MMU配置,......?
BTW:我可能更愿意省略const,因为我们正在修改数据库。static bool createSQLiteFunctions(/*const*/ QSqlDatabase& db)
你可以调试步进sqlite3_create_function代码吗?你能产生痕迹吗?
答案 1 :(得分:1)
sqlite3的QSql驱动程序可以在Qt库中静态链接到sqlite3(使用sqlite3版本的Qt存储库),或者动态使用系统中存在的sqlite3版本(例如,当你进行交叉编译时,在sysroot中)对于ARM)。
当您的应用程序链接的sqlite3版本与Qt中链接的版本不同时,会出现问题,因为这会导致问题,例如静态变量在两个版本中的初始化方式不同。
只有在从Qt检索到的句柄上调用本机sqlite3函数时才会出现此问题,只要调用QSqlDatabase函数,一切都可以正常工作,因为这只使用Qt中静态链接的sqlite3版本。
检查Qt configure选项&#34; system-sqlite&#34;,还要注意在某些版本的Qt中该选项已被破坏(请参阅qtbase存储库中的commit ced4d167a25b)。