2012-05-29 97 views
1

過去,我使用的庫允許我註冊一個回調函數,以便在發生某些事件時庫可以調用我的方法(例如,在使用GUI庫看起來像button.onClick(clickHandler)的代碼中看到的情況很常見)。如何實現回調處理?

天真,我認爲圖書館的處理機制,可以實現這樣的:

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

但是這將是真正的浪費嗎?或者真的是它是如何完成的(例如,像java swing或GTK +這樣熟知的GUI庫這樣做)?

背景:

這個問題並沒有真正發生在我,直到我遇到了curses。我想到實現我自己的回調系統,直到我意識到我不知道如何。

回答

2

while循環通常會等待來自用戶的中斷(Windows中的GetMessage)。當中斷到達時,GetMessage返回,然後結束回調函數。 if語句通常以switch-case的形式實現。請參閱Wikipedia上的Windows消息循環。

更詳細地,會發生什麼情況如下:

用戶應用程序調用的GetMessage,這迫使進程睡眠直至該應用程序的輸入消息從所述系統到達隊列。當消息到達時,用戶應用調用DispatchMessage,該消息調用與消息針對的窗口關聯的回調函數。

Windows API使用一個處理切換案例中所有事件的回調。其他庫代替每個事件類使用一個回調。

函數指針本身與其他窗口數據一起存儲在一個結構中。

0

回撥系統的實施可能有不同的技術不同的實現,但是,我想他們應該以這種方式工作:

  1. 的數據結構存儲回調ID和指針的處理程序。

  2. 回調處理程序有一個驗證

  3. 的事件處理程序回調來電,哪知道什麼是可能的回調,並檢查其有效性是這樣的:

    在event.callbacks每個回調

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

    末爲

  4. 當您添加處理程序函數的SYS TEM會自動知道在哪裏回調是有效的,並會回調添加到所描述的數據結構中的1

糾正我,如果我錯了,這說明只是一個猜測。