2011-03-16 145 views
3

我想構建一個可以隱藏線程創建的「IThread」類。子類實現「ThreadMain」方法,並自動調用它看起來像這樣:如何將void(__thiscall MyClass :: *)(void *)轉換爲void(__cdecl *)(void *)指針

class IThread 
{ 
public: 
    void BeginThread(); 
    virtual void ThreadMain(void *) PURE; 
}; 
void IThread::BeginThread() 
{ 
    //Error : cannot convert"std::binder1st<_Fn2>" to "void (__cdecl *)(void *)" 
    m_ThreadHandle = _beginthread(
        std::bind1st(std::mem_fun(&IThread::ThreadMain), this), 
        m_StackSize, NULL); 
    //Error : cannot convert void (__thiscall*)(void *) to void (__cdecl *)(void *) 
     m_ThreadHandle = _beginthread(&IThread::ThreadMain, m_StackSize, NULL); 
} 

我已經搜索周圍,無法弄清楚。有沒有人做過這樣的事情?或者我走錯路了? TIA

+1

OP沒有使用搜索 – zabulus 2011-03-16 13:53:46

回答

3

你不能。

您應該使用靜態函數(不是靜態成員函數,而是自由函數)。

// IThread.h 
class IThread 
{ 
public: 
    void BeginThread(); 
    virtual void ThreadMain() = 0; 
}; 

// IThread.cpp 
extern "C" 
{ 
    static void __cdecl IThreadBeginThreadHelper(void* userdata) 
    { 
     IThread* ithread = reinterpret_cast< IThread* >(userdata); 
     ithread->ThreadMain(); 
    } 
} 
void IThread::BeginThread() 
{ 
    m_ThreadHandle = _beginthread(
        &IThreadBeginThreadHelper, 
        m_StackSize, reinterpret_cast< void* >(this)); 
} 
+0

靜態成員函數將無法正常工作,如果你有一個符合的編譯器。 _beginthread可能需要一個extern「C」函數,而一個靜態成員不能有「C」鏈接。 (當然,_beginthread是一個Windows特定的函數,而VC++並不考慮extern「C」,所以你可能不會遇到任何問題。) – 2011-03-16 14:00:55

+0

我使用了一個靜態函數,而不是靜態成員函數。他們可以有「C」連接。在這種情況下,使用或不使用「extern」C「'的區別可能僅僅是符號表中的不同名稱。儘管我會更新我的答案。 – 2011-03-16 14:06:12

+0

@詹姆斯:好奇,你是對的。但是它有什麼實際用途嗎?有沒有C和C++鏈接不兼容的編譯器? – 2011-03-16 14:21:38

相關問題