2013-03-21 3 views
0

Пожалуйста, посмотрите на следующий кодфункция Thread определена в заголовочном файле дает ошибки литых типа

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

+0

@chris: Хорошо, значит, вы не можете взять его в файл заголовка? –

+0

@ JesseGood: Нет, это не так. Нет принятых ответов. И нет файла заголовка. –

ответ

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 через объект Server.

+0

hmmm ... Интересно! В любом случае, нежелательные статические вещи могут создавать проблемы в будущем, не так ли? В таком случае мне нужно определить его и инициализировать его внутри., Cpp, а не в .h правильно? –

+0

@Yohan это на самом деле довольно распространенное и абсолютно правильное использование статической функции-члена. Вы просто используете его как «прокладку», чтобы передать аргумент, который вы передаете потоку, в указатель на экземпляр класса, а затем вызывать некоторую функцию-член на этом указателе. Я не знаю, что вы подразумеваете под «инициализацией», поскольку вам не нужно инициализировать функции. Как и все функции-члены, вы можете объявить его в файле заголовка и определить его в отдельном файле '.cpp', или вы можете объявить его в заголовочном файле. –

+0

Спасибо! Я очень ценю вашу помощь :) –