Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++
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
 
 
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 3-Feb-13 12:38pm
canard291.3K
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

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.
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 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 at 7-Feb-13 19:39pm
   
Yes I agree, the wrong type is being passed.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 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 at 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 at 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 at 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 at 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)

  Print Answers RSS
Your Filters
Interested
Ignored
     
0 Sergey Alexandrovich Kryukov 397
1 OriginalGriff 380
2 Shai Vashdi 280
3 Emre Ataseven 135
4 Abhinav S 128
0 Sergey Alexandrovich Kryukov 8,894
1 OriginalGriff 5,200
2 Peter Leow 3,955
3 Maciej Los 3,535
4 Abhinav S 3,208


Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 3 Feb 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Use
Layout: fixed | fluid