How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
I am facing a problem:
I have say 3 files :
ABC.h -- this file has the function prototypes
ABC.cpp -- the definitions of the functions
ABC_Test.cpp --- the file with main() which calls the functions using ABC's object say "ob".
Now I want to make a function say "startNewThread()" inside ABC.cpp and its prototype in ABC.h, then where should I define
static DWORD WINAPI ThreadFunc(LPVOID pvParam);
function. Inside ABC_Test.cpp or inside ABC.cpp
Also Iwill call the createThread() of Win API inside startNewThread() and pass the ThreadFunc as one of its parameters. If this is possible, then its OK. But if I have to call some function of mine say
void ABC :: printXYZ() inside ThreadFunc , then how can I do this. I do not have my object say ABC ob; i.e. "ob" inside my ThreadFunc.
Please reply, if possible with a EXAMPLE code
Pawan
# 1 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
http://msdn2.microsoft.com/en-US/library/ms682453.aspx
So you should cast your 'ob' instance to lpParameter.
CreateThread( ..., ( LPVOID ) &ob, ... );
...
static DWORD WINAPI ThreadFunc(LPVOID pvParam)
{
ABC * ob = ( ABC * ) pvParam;
}
# 2 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
I have tried thiss, and its a success when I just want send an object to the threadFucn() but the problem I am facing is :
I have a socket object say : clientSocket and I am sending this to the threadFunc() as the parameter in CreateThread(). But how can I send more than 1 parameter to the threadFunc() using CreateThread(). For example both clientSocket object and my ABC ob.
Pawan
# 3 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
But how can I send more than 1 parameter to the threadFunc() using CreateThread().
Not complete/compilable code, but to illustrate the point...
class Info
{
public:
SomeClass1 thing1;
SomeClass2 thing2;
int value1;
int value2;
};
{
Into i;
CreateThread(&i);
}
# 4 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
Here's everything in more detail :
The 3 file are :
1) GridServer.h containing function prototypes
DWORD WINAPI runThread(LPVOID Parameter);
void startNewThread(SOCKET c_socket);
2) GridServer.cpp -- the .cpp file with function definitions
DWORD WINAPI GridServer :: runThread(LPVOID Parameter)
{
//Get the information about client entity
SOCKET clientSocket = (SOCKET)Parameter;
printf( "\n New Client Connected.\n");
cout.flush();
int bytesRecv = SOCKET_ERROR;
char *recvbuf;
recvbuf = new char[1];
int ch ;
bytesRecv = recv( clientSocket, recvbuf, 1, 0 );
cout.flush();
printf( "\n Bytes Received: %ld", bytesRecv );
printf("\n Data Received = %c", recvbuf[0]);
ch = atoi(recvbuf);
switch(ch)
{
case 1 : getFile(clientSocket);
break;
case 2 : createAccount(clientSocket,TABLE_OF_INTEREST);
break;
default : printf("\n Invalid option sent from client.");
break;
}
return 0;
}
/******************/
void GridServer :: startNewThread(SOCKET c_socket)
{
HANDLE hThread; //Handle to thread
DWORD ThreadId; //used to store the thread id
/********************/
/***This is line 207 where error occurs****/
/***************************/
/*Line207*/hThread = CreateThread( NULL,
0,
&GridServer::runThread,
(LPVOID)c_socket,
0,
&ThreadId);
//printf("\n After CreateThread()");
return;
}
and
3) GridServer_Test.cpp -- the .cpp with main()
it makes a GridServer object named : "ob" and calls ob.startNewThread(acceptSocket);
here acceptSocket is a variable of type SOCKET.
now the problems are :
when I compile the code, I get the following error :
g:\smartsafe\gridserver\gridserver.cpp(207) : error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (__stdcall GridServer::* )(LPVOID)' to 'LPTHREAD_START_ROUTINE'
There is no context in which this conversion is possible
What should I do?
What I require are :
1) calling the runThread() function properly from startNewThread() using CreateThread().
2)Also if you can see that I am calling getFile() and createAccount() from inside the runThread() I want this to be called, with respect to the object which called startNewThread().
I think I have tried to make my code clear this time.
Please Reply, if more information is required, I will reply
Pawan
# 5 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
Do me a favor and go back and edit your post to highlight the line which the error occurs on. I have problems counting to 207 :D
# 6 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
I haven'T looked at the code, only at the error message.
Your problem is that you want to cast a c++ member function pointer to a static C-style pointer. and this is forbidden, and there is NO way to work around this but one secret hack, and if you would really find this secret hack then it would crash :)
You have two possibilities:
1. use a static C function for the callback
2. use a static C++ member function for the callback
void
function(void) // that's ok
{
}
class C
{
static void member(void); // that's ok
void member(void); // forbidden
};
more information about function pointers and why they are tricky with C++:
http://www.newty.de/fpt/index.html
HTH
chris
# 7 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
Do me a favor and go back and edit your post to highlight the line which the error occurs on. I have problems counting to 207 :D
I have added the line number where error occurs. Now please reply.
Pawan
# 8 Re: How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)
I will study the "newty" links on function pointers, but can anyony reply to the answers which I have posted. They were :
What I require are :
1) calling the runThread() function properly from startNewThread() using CreateThread().
2)Also if you can see that I am calling getFile() and createAccount() from inside the runThread() I want this to be called, with respect to the object which called startNewThread().
Please tell me how to get these 2 things done.
Pawan