3

sqlite3_execいくつかの情報を処理するために、静的 CallBack 関数でSQLite の関数を使用しています。を呼び出したクラスで定義されたファイルに、結果の情報を出力したいと考えていますsqlite3_exec。私が話していることは、ちょっとこのように見えます。

class MakingTheCall{

static int CallBack(void *NotUsed, int argc, char **argv, char **azColName)
{
    for(int x = 0; x < argc; x++)
        File << argv[x];
    File<<"\n";
} 

private:
   static ofstream File;
   void call(){
       sqlite3_exec(database, query, callback, 0, &zErrMsg);
   }
};

私が本当に欲しいのは、静的関数がインスタンス固有のものを使用することFILEです。したがって、どのインスタンスがMakingTheCall呼び出しを行っても、それは一意の非静的FILEオブジェクトを渡します。

しかし、静的であり、(私が思うに) コールバックである必要があるため、クラスCallBackのポインターにアクセスできません。thisしたがって、私の考えは、関数がポインターfriendに到達できる場合です。これは、私がこの投稿を正しくthis理解していることを前提としています。

自分の思考回路に欠陥があると感じています。this関数がどちらを使用するかについては、まだ曖昧な点があるように感じます。

この議論のパート 2 として、静的フレンド メソッドが使用される場所の例はありますか? これらは、最初のコメントでここで読んでいるものとは相互に排他的な修飾子ではないので、いつ両方を使用しますか?

私は SQLite と CallBacks を初めて使用するので、人生を楽にしてくれる何かを見落としている可能性があります。void*ポインターのように、それをどのように使用しますか? やりたいことの鍵のような気がします。

ありがとうございます。

4

3 に答える 3

4

sqlite3_exec()呼び出しでオブジェクト ポインターを渡します。

sqlite3_exec(database, query, callback, (void*) this, &zErrMsg);

そして、コールバックのNotUsedパラメータでそれを取得します:

static int CallBack(void *NotUsed, int argc, char **argv, char **azColName)
{
    MakingTheCall* obj = (MakingTheCall*) NotUsed;

    // whatever....
}

厳密に言えば、関数は静的メンバーではなく、フリー関数でCallback()ある必要があります。extern "C"

于 2012-08-30T16:19:59.043 に答える
4

-support を指定してコンパイルする場合はC++11、無名関数 (ラムダ式) を使用できます。例:

class MakingTheCall
{
private:
   ofstream File;
   void call(){
       sqlite3_exec(database, query,
           [&] (void *NotUsed, int argc, char **argv, char **azColName) -> int
           {
               for(int x = 0; x < argc; x++)
               File << argv[x];
               File<<"\n";
           },
           0, &zErrMsg);
   }
};

[&]で使用可能なすべての変数が、 -pointercallを含めて参照によってキャプチャされることを意味します。this詳しくはこちら(ウィキペディア)をご覧ください。

于 2012-08-30T16:51:23.077 に答える
2

通常、これは、コールバックを登録するときにクロージャーパラメーターの一部としてオブジェクトへのポインターを渡すことによって達成されます。sqlite3_execAPIの場合は以下の通りです。

int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
);

したがって、オブジェクトへのポインターをパラメーター 4 として渡します。コールバック関数はまだ静的ですが、最初に行う必要があるのは、最初のパラメーターを、関心のあるオブジェクトのクラスへのポインターとしてキャストすることです。次のことができます。次に、File渡されたインスタンスに固有の に書き込むことができる目的の関数を呼び出します。したがって、コードは次のようになります。

static int CallBack(void *closure, int argc, char **argv, char **azColName)
{
    MakingTheCall* obj = static_cast<MakingTheCall*>(closure);
    obj->WriteToTheFile(argc, argv);
    return 0; // Have to return something.
}

int WriteToTheFile(int argc, char **argv)
{
    for(int x = 0; x < argc; x++)
        File << argv[x];
    File<<"\n";
} 
于 2012-08-30T16:24:44.760 に答える