gpt4 book ai didi

c++ - 如何使用 QThreadStorage 调用自定义免费?

转载 作者:太空宇宙 更新时间:2023-11-04 02:51:37 24 4
gpt4 key购买 nike

我在 QThreadStorage 中存储的每个线程都有一个 sqlite3* 实例。问题是当我退出时,QThreadStorage 删除了指针。我如何让它改为调用 sqlite3_close?

最佳答案

您需要将 sqlite3* 指针以及 sqlite3_stmt* 包装在 RAII 类中。如果您使用 C++ 而不是 C 进行编程,那么无论如何您都应该这样做 :)

这样的类肯定存在,参见this question例如麻省理工学院许可的 sqlite3pp项目。

不包装所有 API 的非常简单的实现,可以使用转换运算符使实例可以简单地用于 sqlite 的 C 接口(interface)函数。

// https://github.com/KubaO/stackoverflown/tree/master/questions/sqlite-threadstore-21536836
#include <QtCore>
#include <sqlite3.h>

class SQLiteStmt {
Q_DISABLE_COPY(SQLiteStmt)
sqlite3_stmt* m_stmt;
int m_rc;
friend class SQLiteDB;
private:
explicit SQLiteStmt(sqlite3_stmt* stmt, int rc) : m_stmt(stmt), m_rc(rc) {}
public:
SQLiteStmt(SQLiteStmt && o) : m_stmt(o.m_stmt), m_rc(o.m_rc) {
o.m_stmt = nullptr;
}
~SQLiteStmt() { sqlite3_finalize(m_stmt); m_stmt = nullptr; }
int status() const { return m_rc; }
operator sqlite3_stmt*() const { return m_stmt; }
};

class SQLiteDB {
Q_DISABLE_COPY(SQLiteDB)
sqlite3* m_db = nullptr;
public:
SQLiteDB() = default;
int open(const QString & filename) {
close();
return sqlite3_open16(filename.utf16(), &m_db);
}
int close() {
sqlite3* const db = m_db;
m_db = nullptr;
if (db) return sqlite3_close(db);
return SQLITE_OK;
}
int exec(const QString & sql) {
auto stmt = prepare(sql);
int rc = stmt.status();
if (rc == SQLITE_OK) do {
rc = sqlite3_step(stmt);
} while (rc == SQLITE_ROW);
return rc;
}
SQLiteStmt prepare(const QString & sql) {
sqlite3_stmt* stmt;
auto rc = sqlite3_prepare16_v2(m_db, sql.utf16(), -1, &stmt, nullptr);
return SQLiteStmt{stmt, rc};
}
~SQLiteDB() { close(); }
operator sqlite3*() const { return m_db; }
};

int main() {
QThreadStorage<SQLiteDB> dbData;
SQLiteDB & db(dbData.localData());
if (db.open(":memory:") != SQLITE_OK)
qDebug() << "open failed";
if (db.exec("CREATE TABLE myTable(value NUMERIC)") != SQLITE_DONE)
qDebug() << "create failed";
if (db.exec("INSERT INTO myTable VALUES (10), (20), (30)") != SQLITE_DONE)
qDebug() << "insert failed";
auto stmt = db.prepare("SELECT * FROM myTable");
if (stmt.status() == SQLITE_OK) while (true) {
int rc = sqlite3_step(stmt);
if (rc != SQLITE_ROW) break;
qDebug() << sqlite3_column_int(stmt, 0);
}
}

关于c++ - 如何使用 QThreadStorage 调用自定义免费?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21536836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com