CALLBACK回呼函數詳解

來源:互聯網
上載者:User

凡是由你設計卻由windows系統呼叫的函數,統稱為callback函數。某些API函數要求以callback作為你參數之一。如SetTimer,LineDDA,EnumObjects。 回呼函數是由開發人員按照一定的原形進行定義的函數(每個回呼函數都必須遵循這個原則來設計) 例如:---------------------------------------- BOOL CALLBACK DialogProc( HWND hwndDlg, // handle of dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); ----------------------------------------說明:回呼函數必須有關鍵詞 CALLBACK;回呼函數本身必須是全域函數或者靜態函數,不可定義為某個特定的類的成員函數 2 回呼函數並不由開發人員直接調用執行(只是使用系統介面API函數作為起點) 3 回呼函數通常作為參數傳遞給系統API,由該API來調用 4 回呼函數可能被系統API調用一次,也可能被迴圈調用多次 示範EnumObjects,發現某個Device Context的GDI obect 符合我們的形態時,呼叫callback函數. 假設我們有一個CMycalss如下: class CMyclass { private : int nCount; int CALLBACK _export EnumObjectsProc(LPSTR lpLogObject, LPSTR lpData); public : void enumIt(CDC& dc); } void CMyclass::enumIt(CDC& dc) { // 註冊 callback 函式 dc.EnumObjects(OBJ_BRUSH, EnumObjectsProc, NULL); } C++編譯器針對CMyclass::enumIt實際作出的碼相當於: void CMyclass::enumIt(CDC& dc) { // 註冊 callback 函式 CDC::EnumObjects(OBJ_BRUSH, EnumObjectsProc, NULL, (CDC *)&dc); } 你所看到的最後一個參數其實是this指標,類的成員函數靠著this指標才得以抓到正確對象資料. 而nCount = 0;其實是this->nCount = 0; 基於相同的道理,上例中的EnumObjectProc既然是一個成員函數,C++編譯器也會為它多準備一個隱藏參數.問題出現, callback函數給windows呼叫用的,windows並不經由任何對象呼叫這個函數,也就無需傳遞this指標給callback函數,也是導致堆棧中有一個隨機參數會成為this指標,而其結果當然是程式的崩潰了. 因此要把某個函數作為callback函數,就必須告訴C++編譯器,不要放this指標作為該函數的最後一個參數,兩個方法可以做到這一點, 1 .不要使用類的成員函數(也就是說 要使用全域函數) 作為callback函數. 2. 使用static成員函數,也就是在函數前加上static修飾詞. 第一種做法相當於在C語言中使用callback函數,第二種做法接近OO精神.進一步而言,C++中的static函數特性是,即使對象還沒有產生,static成員已經存在(函數或參數都如此).換句話說,物件產生之前你已經可以呼叫類的static函數或者使用類的static變數了;也就是說凡是宣告為static的東西,(不管函數或變數)都並不和對象結合在一起,它們是類的一部分,不屬於對象 Q 回呼函數和鉤子函數有何不同? A: 使用回呼函數實際上就是在調用某個函數(通常是API函數)時,將自己的一個函數(這個函數為回呼函數)的地址作為參數傳遞給那個函數。而那個函數在需要的時候,利用傳遞的地址調用回呼函數,這時你可以利用這個機會在回呼函數中處理訊息或完成一定的操作。至於如何定義回呼函數,跟具體使用的API函數有關,一般在協助中有說明回呼函數的參數和傳回值等。C++中一般要求在回呼函數前加CALLBACK,這主要是說明該函數的調用方式。 至於鉤子函數,只是回呼函數的一個特例。習慣上把與SetWindowsHookEx函數一起使用的回呼函數稱為鉤子函數。也有人把利用VirtualQueryEx安裝的函數稱為鉤子函數,不過這種叫法不太流行。 frank的意見: 回呼函數就是一個處理函數,由系統在符合你設定的條件時自動調用。為此,你需要做三件事:1,聲明;2,定義;3,設定觸發條件,就是在你的函數中把你的回呼函數名稱轉化為地址作為一個參數,以便於系統調用。 聲明和定義時應注意:回呼函數由系統調用。不要把它當作你的某個類的成員函數。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.