Click here to Skip to main content
15,881,588 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How to add (void*)clientSocket as a parameter in ThreadHandleClientThreadFunction ?


main.h
class Networker
{
public :
	Networker(u_short port);
	~Networker();

...
	void ServerThreadFunction();
	void HandleClientThreadFunction(void* parameters);

	static void __cdecl ThreadHandleClientThreadFunction(void * pThis)
  {
	  static_cast<Networker*>(pThis)->HandleClientThreadFunction();  //ERROR HERE
  };

	static void __cdecl ThreadServerThreadFunction(void * pThis)
  {
	  static_cast<Networker*>(pThis)->ServerThreadFunction();  
  };


Main.cpp

C++
void Networker::HandleClientThreadFunction(void *parameters) 
{
	// Input parameter is the client socket
	SOCKET clientSocket = (SOCKET)parameters;

}

void Networker::ServerThreadFunction()
{
....
for (;;)
{
		// Wait for a new client
		clientSocket = accept(listenSocket, NULL, NULL);

		// Check if new client is valid
		if(clientSocket == INVALID_SOCKET)
		{
			closesocket(listenSocket);
			break;
		}

		// Start a new thread to handle the new client
		_beginthread(ThreadHandleClientThreadFunction, 0, (void*)clientSocket);
}
}
Posted

Hello again. I think you need to be passing a pointer to the Networker instance rather than the clientSocket judging by what your thread function does with the pointer.
Also the cast in the thread function should be a reinterpret_cast. I don't think a static cast will cut it to turn a void* back into a class instance pointer unless they've changed the rules on me in C++11.
Possibly also your clientSocket needs to be a member of Networker rather than a local variable but I can't really say without seeing the whole code.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 7-Feb-13 18:29pm    
Please see our discussion in comments under the solution by Espen.
Yes, Networker wraps the thread, so its instance is the best to pass. But the bug is clear: can you see that in thread entry point, Networker pointer is expected, but socket is passed to _beginthread. No wonder it messes up things quite well. :-) (I up-voted the answer by 4.)
—SA
Matthew Faithfull 7-Feb-13 19:39pm    
Yes I agree, the wrong type is being passed.
The technique you need is explained in detail in many places. See for example:
http://stackoverflow.com/questions/5968076/passing-parameters-to-beginthreadex[^].

The idea is: the parameter next to your thread entry point address is the void pointer used to pass any data to this entry point function; so, you pass the address of your data via this pointer, and this data will be passed to your function; when this function is called in your newly created thread, you will need to case this void pointer back to the pointer to your data structure. You will find the code samples in the answers referenced above.

—SA
 
Share this answer
 
v2
Why don't you change:
_beginthread(ThreadHandleClientThreadFunction, 0, (void*)clientSocket);

to:
_beginthread(ThreadHandleClientThreadFunction, 0, (void*)this);


Now, this:
static_cast<networker*>(pThis)->HandleClientThreadFunction();  //ERROR HERE

should not even compile, as HandleClientThreadFunction is declared as:
void HandleClientThreadFunction(void* parameters);


Best regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 7-Feb-13 18:00pm    
Right idea, a 5.
However, in most cases, most general and robust idea is this: wrap the thread in a class and pass an instance of the wrapper to the thread. This way, everything else will be accessible via this instance, like as with "this" parameter.
—SA
Espen Harlinn 7-Feb-13 18:12pm    
Thank you, Sergey :-D

It seems that this is what OP actually attempted, but botched it by passing clientSocket instead of this to the _beginthread function, but the thread function seems to expect that the argument should be a pointer to this:

static void __cdecl ThreadHandleClientThreadFunction(void * pThis)
{
static_cast<networker*>(pThis)->HandleClientThreadFunction(); //ERROR HERE
};

Which causes the code to fail.
Sergey Alexandrovich Kryukov 7-Feb-13 18:27pm    
Oh... I can see, there is just a mess: Networker is expected, but socket is passed to _beginthread.
I guess Matthew Faithfull is right, even if he did not see where is the bug exactly...
—SA
Espen Harlinn 7-Feb-13 18:30pm    
Yes, and if OP had placed a breakpoint on the offending line, he could easily have determined this by inspecting the type of pThis in the local variables pane.
Sergey Alexandrovich Kryukov 7-Feb-13 18:34pm    
True!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900