2016-08-08 17 views
0

Visual Studio 2010でMFCダイアログでSQLiteを使用しようとしています。コールバック関数を使用してクエリの結果を保存する方法が不明です私のデータベース内のテーブルの数を変数m_Resultsに数えます。とにかくこれを行うには、またはnTables変数にアクセスするためにとにかく私にはありますか?C++ MFC SQLite sqlite3_execコールバック

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 
} 

答えて

1

sqlite3_exec APIのコールバックは広くunderdocumentedです。誤解を招くパラメータ名であると主張されているという事実も、あまり役に立ちません。 callbackからm_Resultsオブジェクトを更新するには

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 

、あなたは、単に正しい型にコンテキストをキャストする必要があり、それを使用します:長い道のりを行くより自然な正式なパラメータ名を提供

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; 

&m_Resultsからsqlite3_exec()の代わりにthisを渡し、コールバックからパブリッククラスのメンバーを呼び出すことができます。

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); 
+0

あなたの答えをありがとう。私はあなたに解決策を試みましたが、エラーが発生しました。 results + = columnNames [index]; 2つのポインタをどのように連結しますか? –

+0

@ J.Ting:関数にCStringを渡します。なぜあなたは既にMFCを持っているのであれば、ポインタに気をつけているでしょう – cha

+0

@ J.Ting:あなたは私たちに何も言わなかったので、どんなタイプの 'm_Results'があるのでしょうか?この回答は、データをコールバックに渡す方法を示しました。あなたは、そのデータを自分で使用する際の詳細を調べなければなりません。 – IInspectable

関連する問題