2013-03-21 44 views
0

請看看下面的代碼線程功能是給類型轉換錯誤

Server.h

#pragma once 
class Server 
{ 
public: 
    Server(void); 
    ~Server(void); 

    DWORD WINAPI serverThread(LPVOID param); 

private: 
    SOCKADDR_STORAGE from; 
    int retval, fromlen, socket_type; 
    char servstr[NI_MAXSERV],hoststr[NI_MAXHOST]; 
    SOCKET serverSocket, acceptSocket; 
}; 

Server.cpp

小部分顯示在這裏。

Server:Server() 
{ 
//Code 

//Passing data to thread 
     DWORD threadId; 
     HANDLE hdl; 

     hdl = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE) serverThread,(LPVOID)acceptSocket,0,&threadId); 

//Code 
} 


DWORD WINAPI Server::serverThread(LPVOID param) 
{ 
//code 
} 

此代碼生成錯誤

error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'LPTHREAD_START_ROUTINE' 

即從線

hdl = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE) serverThread,(LPVOID)acceptSocket,0,&threadId); 

這是爲什麼?請幫忙!

+2

「DWORD(WINAPI Server :: *)(LPVOID)」不是「DWORD(WINAPI *)(LPVOID)」。 – chris 2013-03-21 20:24:12

+0

@chris:好的,你的意思是它不能被帶入頭文件? – 2013-03-21 20:33:52

+0

@JesseGood:不,它不是。沒有被接受的答案。沒有頭文件。 – 2013-03-21 20:37:07

回答

5

非靜態方法的類型不同於靜態方法或全局方法。請記住,非靜態成員函數有一個隱藏參數這是this指針,所以在本質上你的serverThread函數有這樣的簽名:

DWORD WINAPI serverThread(Server *this, LPVOID param); 

所以,你可以看到爲什麼這不起作用(並不會工作甚至與演員 - 怪異的恐怖將會發生)。

爲了使其與LPTHREAD_START_ROUTINE兼容,你需要使它靜態的,因爲靜態成員函數不要在類的特定實例的操作,因此不需要this指針:

static DWORD WINAPI serverThread(LPVOID param); 

強似acceptSocket作爲對lpParameter參數CreateThread的,通過

hdl = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)serverThread, this,0,&threadId); 

裏面serverThread你仍然可以訪問acceptSocket成員通過服務器對象。

+0

嗯...有趣!無論如何,不​​需要的靜態的東西可以使未來的問題是不是?在這種情況下,我需要對它進行定義並初始化它,而不是在.h中。 – 2013-03-21 20:45:40

+0

@Yohan這實際上很常見,並且是靜態成員函數的完全有效使用。您只需將其用作「填充程序」即可將傳遞給線程的參數轉換爲指向該類實例的指針,然後在該指針上調用某個成員函數。由於您不必初始化函數,因此我不知道「初始化」是什麼意思。像所有成員函數一樣,您可以在頭文件中聲明它,並將其定義在單獨的'.cpp'文件中,或者可以在頭文件中聲明它。 – 2013-03-21 21:05:48

+0

謝謝!我真的很感謝你的幫助:) – 2013-03-22 05:14:04