有時候,我們在使用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定時器的回調函數這個問題,當然在編程中不推薦這麼使用(有很多替代方法)。