【发布时间】:2021-02-11 21:51:23
【问题描述】:
我正在尝试使用 sqlite 将自定义整理功能添加到 qt 项目中。 我遇到了一个我不理解的段错误,因此无法修复。
它来自以下代码,在 sqlite3_create_collation sql 函数中。
bool create_collate(QSqlDatabase *db)
{
QVariant v = db->driver()->handle();
if (!v.isValid() || qstrcmp(v.typeName(), "sqlite3*") != 0)
return -1;
sqlite3* sql_db = *static_cast<sqlite3* const*>(v.data());
if (!sql_db)
return -1;
sqlite3_initialize();
--> return sqlite3_create_collation(sql_db, "NOACCENTS", SQLITE_UTF8, NULL, &localeCompare); <--
}
segv 在到达这个特定函数时发生,在突出显示的行上:
static HashElem *findElementWithHash(
const Hash *pH, /* The pH to be searched */
const char *pKey, /* The key we are searching for */
unsigned int *pHash /* Write the hash value here */
){
HashElem *elem; /* Used to loop thru the element list */
unsigned int count; /* Number of elements left to test */
unsigned int h; /* The computed hash */
static HashElem nullElement = { 0, 0, 0, 0 };
if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
struct _ht *pEntry;
h = strHash(pKey) % pH->htsize;
pEntry = &pH->ht[h];
--> elem = pEntry->chain; <--
count = pEntry->count;
}else{
h = 0;
elem = pH->first;
count = pH->count;
}
if( pHash ) *pHash = h;
while( count-- ){
assert( elem!=0 );
if( sqlite3StrICmp(elem->pKey,pKey)==0 ){
return elem;
}
elem = elem->next;
}
return &nullElement;
}
sqlite -version的输出是3.32.3,和qt使用的版本一致,也是3.32.3。
编辑:
地区比较:
int localeCompare(void *, int len1, const void *data1, int len2, const void* data2)
{
auto qstr1 = QString::fromUtf8(reinterpret_cast<const char*>(data1), len1 * 4);
auto qstr2 = QString::fromUtf8(reinterpret_cast<const char*>(data2), len2 * 4);
int end = 0;
while (qstr1[end] != '\0') {end++;}
qstr1.truncate(end + 1);
end = 0;
while (qstr2[end] != '\0') {end++;}
qstr2.truncate(end + 1);
return QString::compare(BkString::removeAccents(qstr1), BkString::removeAccents(qstr2), Qt::CaseInsensitive);
}
Qt 已通过在线安装程序安装完毕。
对应的.pro:
QT += core sql quick qml
QT -= gui
TEMPLATE = lib
CONFIG += unversioned_libname unversioned_soname # do not generate the symbolic link.
!android {
LIBS += -lsqlite3 -ldl
}
TARGET = bkdatabase-core
INCLUDEPATH += ./src
SOURCES += ...
HEADERS += ...
一个最小的例子是:
#include <sqlite3.h>
#include <QSqlDatabase>
int main(void)
{
QSqlDatabase db("QSQLITE");
db.setDataBaseName("My_db");
if (db.open())
create_collate(&db);
return 0;
}
【问题讨论】: