いつもお世話になります。今 VC++6.0で開発しています。EnumWindowを利用する際に
CallBack関数という言葉がでてきました。しかしCallBack関数って一体どのようなもの
かがよくわかりません。
私のイメージでは自作関数で処理やイベントを横取りするみたいなイメージをもって
いるのですが、間違っていますか??私の持っているイメージに間違っているのでした
らご指摘およびご教授お願いします
> 私のイメージでは自作関数で処理やイベントを横取りするみたいなイメージをもっているのです
が、
> 間違っていますか??私の持っているイメージに間違っているのでしたらご指摘およびご教授お願
いします
イベントに対するコールバックとしては、そのような用途に使うことも多いので、
イメージは大きく外れてはいないと思います。
但し、もともと Callback 自体はそれに限定されるものではなく、
単にその名の通り「呼び返してもらう」こと/そのためのものです。
通常の関数のようにこちらの都合で呼び出すのではなく、関数を教えておいて、
向こうから呼び返し直してもらうのが、Callback というものの動作です。
# 電話とかを折り返してもらうのも Callback
EnumWindow であれば、ウィンドウを見つけるたびに「こんなのがあったよ」と関数を呼び出して
教えてくれ、その呼び出し先が Callback 関数です。
イメージとしては
「折り返しお電話致しますので電話番号をいただけますか?」
が近いと思う。
折り返しお電話→ callback関数
電話番号→ 関数へのポインタ
Banさん。επιστημηさん。ご解説ありがとうございます。お二人の記事を読み少し
論点は違いますが質問があります。
まだまだ私の理解不足でありまして完全なるイメージが掴めていないのですが
Callbackの利点ってあるのでしょうかね?? 関数って必要なときに呼び出せばだけで
いいのでは??と疑問が思いました。的外れな質問であるかもしれませんが よろしく
お願いします。
> 関数って必要なときに呼び出せばだけでいいのでは??
その「必要なとき」ってのがOSにしかわからなかったら?
プログラムによっては呼び出すだけで十分だね。
それにコールバックって面倒だし。
MFCなしWinアプリ作ったことないのかな。
ウィンドウプロシージャもコールバックだ。
EnumWindowsの場合は
確かにコールバックだと面倒と感じますね。
これの利点は知りません。
# 配列に入れて後でじっくり処理すると
# ウィンドウが削除されていたりするからか?
# まぁ、そんなことどうでもいいや
それ以外に関しては利点というか必要だから存在する。
たとえば、並べ替えのsortでは
色々な構造体でも並べ替えできるようにするために
二つを比較して順序を調べるコールバックがある。
それぞれに一長一短がありますし、利点も欠点もあると思います。
適材適所で使い分けるようにするのが理想でしょう。
現実に置き換えて、電話での依頼という例で言えば、
■普通の関数(同期呼出)というのは、
電話をかけて要件を告げ、その場で結果を聞いて電話を切る。
この方式が向いてないのは、いつ終わるかわからない/時間がかかる依頼です。
「ただいま対応中ですので、お電話はそのままでしばらくお待ちください」とか言われ、
保留音を聞き続けることになります。
ナンセンスな例だと「雨が降りましたらお知らせしますので、お電話はそのままで…」
■スレッドなどで実処理を行う関数(非同期呼出)だと、
電話をかけて要件を告げ「では、お願いします」と言って電話を切ります。
相手が勝手にやってくれ、自分は結果を知らなくてもかまわない依頼ならよいのですが、
結果を知りたい場合、こちらの連絡先(コールバック関数のアドレス)を相手に告げていな
いと、
「先ほどお電話した Ban ですが…終わってますか」
とこちらから確認の電話を入れる必要が出てきます(ポーリング)。
■コールバック関数を登録しての依頼というのは、
電話をかけて要件を告げ、「これこれこういう場合は、ここまで連絡してください」と
お願いすることになります。
長い処理だと、「終わったら教えてください」とかもありえます。
そうすると、相手から「終わりました(完了通知)」とか
「a と b があるんですが、これはどちらが小さいんでしょうか(ソート条件)」とか
「c がまず見つけましたけど(列挙)」とかいう連絡が来ます。
そういうときの応答をコールバック関数に書いておくと、受付担当の人が、
「a と b なら a の方が小さいってことにしてください」とか
「c ですね。伝えておきますので、引き続き列挙の方をお願いします」とか
答えてくれるわけです。
手忙しいときにコールバックがかかってくると面倒なこともあります(排他制御とか)
** ** **
> EnumWindowsの場合は確かにコールバックだと面倒と感じますね。
-- snip --
> # まぁ、そんなことどうでもいいや
おそらくその通りです。コールバック時点での対象 Window の存在保証のため。
また、列挙途中でもお目当てが見つかった時点で中断できるため、でしょうか。
<MSDN>
EnumWindows
-- snip --
この関数を呼び出すと、GetWindow 関数をループ処理で呼び出すよりも信頼性の高い結果
が得られます。
GetWindow 関数を呼び出してトップレベルウィンドウを列挙すると、無限ループに陥った
り、
すでに破棄されているウィンドウのハンドルを参照する危険性がでてきます。
</MSDN>
Banさん。επιστημηさん。超初心者。Banさん。ありがとうございます。
みなさんのご意見を元に以前より イメージを掴むことができました。わかりやすい例
えを挙げていただいて本当にありがとうございます。
また何かありましたらよろしくお願いします。