【问题标题】:C++ MFC SQLite sqlite3_exec callbackC++ MFC SQLite sqlite3_exec 回调
【发布时间】:2016-12-14 00:12:36
【问题描述】:

所以我试图在 Visual Studio 2010 中将 SQLite 与 MFC 对话一起使用。我不清楚如何使用回调函数来保存查询的结果,它试图计算表的数量在我的数据库中,进入变量 m_Results。有没有办法做到这一点,或者无论如何我可以访问 nTables 变量?

static int callback(void *data, int argc, char **argv, char **azColName){
    int i;
    fprintf(stderr, "%s: ", (const char*)data);
    data = argv[0];
    return 0;
}

BOOL CDBpracticeDlg::OnInitDialog(){
    ...

    // TODO: Add extra initialization here
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc;
    char *sql;
    const char* data = "Callback function called";

    rc = sqlite3_open("structInfo_Test.db", &db);

    if( rc ){
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return(0);
    }else{
        fprintf(stderr, "Opened database successfully\n");
    }

    /* Create SQL statement */
    sql = "Select Count(*) as nTables FROM sqlite_master where type='table';";

    /* Execute SQL statement */
    rc = sqlite3_exec(db, sql, callback, &m_Results, &zErrMsg);
    if( rc != SQLITE_OK ){
        char error[200];
        strcpy(error,"SQL error: ");
        strcat(error,zErrMsg);
        m_Results = error;
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }else{
        fprintf(stdout, "Operation done successfully\n");
    }
    UpdateData(FALSE);
    sqlite3_close(db);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

【问题讨论】:

    标签: c++ visual-studio sqlite callback mfc


    【解决方案1】:

    sqlite3_exec API 的回调被广泛记录不足。据称它带有误导性的参数名称这一事实也无济于事。提供更自然的形式参数名称大有帮助:

    static int callback(void* context,  // user-provided object (4th param to sqlite3_exec)
                        int columnCount,      // number of columns
                        char** columnValues,  // array of column values as C-style strings
                        char** columnName)    // array of column names as C-style strings
    

    要从callback 更新m_Results 对象,您只需将context 转换为正确的类型,然后使用它:

    static int callback(void* context, int columnCount,
                        char** columnValues, char** columnNames) {
        CMyType& results = *static_cast<CMyType*>(context);
        // Use 'results' which is a reference to 'm_Results'.
        for (int index = 0; index < columnCount; ++index) {
            // Assuming CMyType has operator+=(const char*) (like a CString)
            results += columnNames[index];
            results += ": ";
            results += columnValues[index];
        }
        // Return 0 to continue invoking the callback for the remaining rows in the result
        // set. Returning non-zero will terminate the callbacks, and sqlite3_exec()
        // returns SQLITE_ABORT.
        return 0;
    

    作为替代方案,您可以将this 代替&amp;m_Results 传递给sqlite3_exec(),并从您的回调中调用一个公共类成员:

    static int callback(void* context, int columnCount,
                        char** columnValues, char** columnNames) {
        CDBpracticeDlg* obj = static_cast<CDBpracticeDlg*>(context);
        // Delegate callback to class member implementation
        return obj->MyCallback(columnCount, columnValues, columnNames);
    }
    
    ...
    
    rc = sqlite3_exec(db, sql, callback, this, nullptr);
    

    【讨论】:

    • 感谢您的回答。我尝试了您的解决方案,但结果出现错误 += columnNames[index];如何连接两个指针?
    • @J.Ting:将 CString 传递给函数。如果您已经拥有 MFC,为什么还要麻烦指针
    • @J.Ting:既然你从来没有告诉我们,m_Results 是什么类型,我只好假设一个。这个答案演示了如何将数据传递给回调。您必须自己制定使用该数据的详细信息。
    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 2012-06-27
    相关资源
    最近更新 更多