1

以前は、コールバックを登録できるライブラリを使用して、イベントが発生したときにライブラリがメソッドを呼び出せるようにしました(たとえば、GUIライブラリを使用するコードで次のように表示されるのが一般的ですbutton.onClick(clickHandler))。

単純に、ライブラリの処理メカニズムは次のように実装できると思います。

while(1){
  if (event1) { event1Handler(); }
  if (event2) { event2Handler(); }
  ...
}

しかし、それは本当に無駄ですよね?それとも、それは本当にそれが行われる方法ですか(たとえば、Java Swingのようなよく知られたGUIライブラリを実行するか、GTK +はこのように実行します)?

バックグラウンド:

私が呪いに遭遇するまで、この質問は私には実際には起こりませんでした。方法がわからないことに気付くまで、自分のコールバックシステムを実装することを考えました。

4

2 に答える 2

2

whileループは通常、ユーザーからの割り込みを待ちます(WindowsではGetMessage)。割り込みが到着すると、GetMessageが戻り、コールバック関数で終了します。ifステートメントは通常、スイッチケースとして実装されます。ウィキペディアのWindowsメッセージループを参照してください。

より詳細には、次のようになります。

ユーザーアプリケーションはGetMessageを呼び出します。これにより、そのアプリケーションの入力メッセージがシステムキューから到着するまで、プロセスが強制的にスリープ状態になります。メッセージが到着すると、ユーザーアプリはDispatchMessageを呼び出します。これは、メッセージの対象となったウィンドウに関連付けられたコールバック関数を呼び出します。

Windows APIは、switchケースのすべてのイベントを処理する1つのコールバックを使用します。他のライブラリは、代わりにイベントクラスごとに1つのコールバックを使用します。

関数ポインタ自体は、他のウィンドウデータと一緒に構造体に格納されます。

于 2012-05-29T11:54:26.910 に答える
0

コールバックシステムの実装は、おそらくテクノロジーごとに実装が異なりますが、次のように機能する必要があると思います。

  1. データ構造には、コールバックIDとハンドラーへのポインターが格納されます。

  2. コールバックハンドラーにはバリデーターがあります

  3. イベントハンドラーにはコールバック呼び出し元があります。コールバック呼び出し元は、可能なコールバックを認識し、次の方法でその有効性を確認します。

    event.callbacksのコールバックごとに

    if (callback.isValid())
    
        call callback()
    
    end if
    

    のために終わる

  4. 関数にハンドラーを追加すると、システムはコールバックが有効な場所を自動的に認識し、1で説明されているデータ構造にコールバックを追加します。

私が間違っている場合は訂正してください。この説明は単なる推測です。

于 2012-05-29T11:58:53.230 に答える