使用類的成員函數作爲API定時器的回調函數

      有時候,我們在使用API定時器時,需要使用類的成員函數作爲其回調函數,但是,編譯器爲了保護成員函數,編譯是不能通過的。那麼我們怎麼才能使用類的成員函數作爲API定時器的回調函數呢?我們可以嵌入一段彙編代碼來繞過編譯器的檢查。舉個例子:

      假設我們一個類的成員函數定義爲void CALLBACK EXPORT CTestDlg::TimerProc,那麼我們在使用API定時器時如果直接這麼寫是編譯通不過的:

::SetTimer(m_hWnd,1,1000,TimerProc);

      使用嵌入一段彙編代碼的解決方法如下:

TIMERPROC tProc;
__asm
{
        mov eax,TimerProc  //將TimerProc函數地址存入eax寄存器
        mov tProc,eax    //將eax寄存器中的值賦值給tProc
}
::SetTimer(m_hWnd,1,1000,tProc);

      通過這麼做,我們可以通過編譯了,但是這麼做會產生一個問題,當進入TimerProc函數體內,發現this指針爲空,而直接調用該函數this指針是正常的。爲了解決這個問題,我們可以定義一個全局指針變量pThis,用來全局保存this指針。然後在TimerProc函數體內使用pThis指針訪問類的成員變量和成員函數。或者在函數開頭使用一段彙編代碼,用來糾正this指針:

__asm
{
    mov ecx,pThis //寄存器ecx用來存放this指針的地址
    mov this,ecx
}

      通過以上步驟就解決了使用類的成員函數作爲API定時器的回調函數這個問題,當然在編程中不推薦這麼使用(有很多替代方法)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章