把系統CALLBACK函數封裝到C++類裡

來源:互聯網
上載者:User

在《定製一個eVC上的中文模擬器》一文回複中,bxianch朋友問到“EVC中的線程,為什麼要聲明稱 static呢,而在靜態函數中藥調用非靜態成員還不能調用,必須把這些成員也設定成靜態,不怎麼方便,有好的解決方案嗎”。

其原因是把CALLBACK函數封裝成C++類的非靜態成員後,需要有建立對象,再通過對象才能去找到這個成員函數。而系統調用這個CALLBACK函數的時候,才不管你有沒有建立對象呢。典型的解決方案是需要用靜態成員函數給系統CALL。然後設法把THIS指標傳給這個STATIC函數,讓這個STATIC函數通過THIS指標訪問到當前對象裡的成員函數,那麼這個成員函數就可以輕鬆操作所有成員變數了。這種方法適用於所有系統CALLBACK。

以CreateThread為例,

class CTest
{
public:
 CTest();
 ~CTest();
 static DWORD WINAPI ThreadCallback(PVOID pParam);   //這個是系統要的東東,沒有對象也能直接存取STATIC成員函數
 DWORD MyProc();
private:
 HANDLE m_hThread;
};

CTest::CTest()
:m_hThread(NULL)
{
 m_hThread = CreateThread(NULL, 0, ThreadCallback, (LPVOID)this, 0, NULL);  //注意把THIS指標當做PARAM傳進去,沒這個我們就不用玩了
 ASSERT(m_hThread);
}

CTest::~CTest()
{
 if(m_hThread)
 {
  TerminateThread(m_hThread, 1);
  m_hThread = NULL;
 }
}

static DWORD WINAPI CTest::ThreadCallback(PVOID pParam)
{
 ((CTest*)pParam)->ThreadProc();  //把pParam還原成指向當前對象的指標,然後曲線救國一下
}

DWORD CTest::MyProc()   //這個就是對象裡的東西了,在裡面可以為所欲為
{
 //do whatever you want
 //even visit the private member
}

如果在ThreadCallback函數裡拿到this指標後,通過this指標去訪問對象裡的東西也是可以的,就不需要多一個MyProc函數了。但是MyProc可以直接引用所有成員變數,而ThreadCallback裡每次都得用this->xxxx訪問,多一次地址跳轉,在效率上會比MyProc裡直接調用稍低一些。所以還是推薦用上面代碼的實現方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.