gpt4 book ai didi

c++ - 如何在 C++ 中获取通过 C 回调返回的结果

转载 作者:行者123 更新时间:2023-11-30 02:38:40 27 4
gpt4 key购买 nike

我不太熟悉在 C++ 中处理 C 回调。我制作了一个 sqlite 包装器 c++ 类,它只调用 sqlite3_exec()。

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
SqliteAccessor* sqlite = static_cast<SqliteAccessor*> NotUsed;
if(argc > 0) {
sqlite->set_table_exists(true);
}
return 0;
}

class SqliteAccessor{
public:
bool has_table(const string dbName, const string tblName)
{
string sql;
sql = "SELECT " + quote_string(tblName) + "FROM " + quote_string(dbName)
+ "WHERE type = 'table' AND name = " + quote_string(tblName) + ";";
char *zErrMsg = 0;
int rc = sqlite3_exec(m_db, sql.c_str(), callback, (void*) this, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s", zErrMsg);
sqlite3_free(zErrMsg);
}
// anyway to return the result directly?
// return hasTable;
}

// can I avoid the following methods and the member variable?
void set_table_exists(bool isExist) { m_table_exist = isExist; }
bool get_table_exists() { return m_table_exist; }
private:
static bool m_table_exist;
};

int caller(){
SqliteAccessor sqlite;
// to check if table exist
if (sqlite->has_table()){
// will above work or
// I should do with an extra call to query the changed state?
}
}

现在,我很困惑调用者如何从 sqlite 包装器中获取结果。我认为,调用者不能通过简单地调用 has_table() 获得结果,因为结果是通过 set_table_exists() 从回调中返回的。因此,调用者应通过进行另一个调用来获得结果,例如调用 sqlite->get_table_exists() ?

然后这意味着对于每个回调,我需要在类 SqliteAccessor 中创建一个成员变量(也必须是 static),以及一对 set/get_state(),会很麻烦。

如何设计类以使其易于调用者使用?不幸的是,我们的代码库不支持 c++11。

最佳答案

如果您使用的是 C++11,请考虑使用 lambda 而不是回调。

class SqliteAccessor{    
public:
bool has_table(const string dbName, const string tblName)
{
bool hasTable = false;
string sql;
sql = "SELECT " + quote_string(tblName) + "FROM " + quote_string(dbName)
+ "WHERE type = 'table' AND name = " + quote_string(tblName) + ";";
char *zErrMsg = 0;
int rc = sqlite3_exec(m_db, sql.c_str(), [&](void *NotUsed, int argc, char **argv, char **azColName){
SqliteAccessor* sqlite = static_cast<SqliteAccessor*> NotUsed;
if(argc > 0) {
hasTable = true;
}
}
, (void*) this, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s", zErrMsg);
sqlite3_free(zErrMsg);
}
return hasTable;
}
};

如果您无法访问 C++11,您始终可以手动编写仿函数。但是,您会失去一些简洁性和地方性。好的部分是仿函数可以保存您需要的状态。

struct callback{
bool operator(void *NotUsed, int argc, char **argv, char **azColName)
{
SqliteAccessor* sqlite = static_cast<SqliteAccessor*> NotUsed;
if(argc > 0) {
hasTable = true;
}
return false;
}
bool hasTable;
};


class SqliteAccessor{
public:
bool has_table(const string dbName, const string tblName)
{
bool hasTable = false;
string sql;
sql = "SELECT " + quote_string(tblName) + "FROM " + quote_string(dbName)
+ "WHERE type = 'table' AND name = " + quote_string(tblName) + ";";
char *zErrMsg = 0;

callback c;
int rc = sqlite3_exec(m_db, sql.c_str(), c, (void*) this, &zErrMsg);
if( rc != SQLITE_OK ){
printf("SQL error: %s", zErrMsg);
sqlite3_free(zErrMsg);
}
return c.hasTable;
}
};

关于c++ - 如何在 C++ 中获取通过 C 回调返回的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30595573/

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