3

私はlibcurlを使用しています。クラスの中で、プログレス関数を見たいファイルをダウンロードしています。私は普通の関数ポインタを設定することができます。libcurlでメンバ関数ポインタを使うにはどうすればいいですか?

curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, progress_func3); 

しかし、私はそれを私のクラスへの関数ポインタに設定したいと思います。

curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, &MyClass::progress_func3); 

progress_func3関数が呼び出されるコードを取得できます。問題は、返されるとすぐに「バッファオーバーランが検出されました!」です。プログラムを安全に継続して実行することができないと言って終了する必要があります。 (これはMicrosoft Visual C++ランタイムライブラリのエラーウィンドウです。私はVisual Studio 2010を使用しています)。

関数を使用すると問題はありませんが、メンバー関数ポインタを使用するとこのエラーが発生します。 libcurlでメンバ関数ポインタを使うには?

答えて

5

非スタティックメンバ関数は、呼び出し可能なポインタthisを必要とします。このタイプのインターフェイスにはthisポインターを指定することはできません。したがって、非静的メンバー関数を使用することはできません。

コールバックとして「プレーンC」関数を作成し、その関数が適切なMyClassインスタンスのメンバー関数を呼び出すようにする必要があります。その後

int my_progress_func(void *clientp, ...) 
{ 
    MyClass *mc = static_cast<MyClass*>(clientp); 
    mc->your_function(...); 
    return 0; // or something else 
} 

のようなものを試してみてください

curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA,  &your_myclass_object); 
curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, my_progress_func); 

(あなたが進捗データに何かが、MyClassポインタを添付する場合は、明らかに、ここではタイプの一致のために責任があります。あなたはあなた自身である)

+0

どのように私のクラスを呼び出すことができますか?進捗機能には自動的に送信される所定のパラメータがあります – judeclarke

+0

私の編集を見ましたか? – Mat

+0

間違ったタイミングでページのリフレッシュを行う必要があります。それは完璧に働いた、ありがとう。 – judeclarke

1

これは、boost :: bind()を使用して行うことができます。たとえば、

boost::bind(&MyClass::progress_func3, this); 

は、voidを返し、引数を持たないメソッドへのポインタです。あなたのコールバックは引数が必要な場合は、次のようにプレースホルダを使用します。

boost::bind(&MyClass::progress_func3, this, _1, _2) 

thisポインタがMyClassのインスタンスをポイントと交換することができます。

EDIT: boost :: function <>と関数ptr型は比較的互換性があるはずです。たとえば:

typedef boost::function< void (int, short) > Callback; 

typedef void (Callback)(int); 

と等価であるあなたは、コンパイラを幸せにするために、間に機能し、それを階層化する必要があります。私はboost :: function <>を使ってコールバックを定義し、正規関数ポインタを渡したことを知っています。

+0

これはどうやって正確に動作するのですか?私はコールバックとしてboost ::関数を渡す方法を見つけることができないようです。 – Mat