Threaded class functions?

Started by
4 comments, last by Fruny 19 years, 8 months ago
Are these possible? I have a class with the DWORD CALLBACK function(); defined as a private member of that class, but I keep getting "cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long (__stdcall *)(void *)" when I call CreateThread(), wether I have NETWORK::ThreadedReceive and just ThreadedReceive as the third param.

void NETWORK::Receive()
{
	if(!receiving&&started_up)
	{
		receiving=true;
		DWORD dwThreadId=1; 
		HANDLE AcceptThread;
		AcceptThread = CreateThread( 
			NULL,                        // default security attributes 
			NULL,                           // use default stack size  
			NETWORK::ThreadedReceive,				 // thread function 
		    NULL,						 // argument to thread function 
		    NULL,                           // use default creation flags 
		    &dwThreadId);                // returns the thread identifier 
	}
}
//***********************************************************
DWORD CALLBACK NETWORK::ThreadedReceive(LPVOID lParam)
{
	char temp_buffer[30];
	int result;
	COORD message={0,4},temp={0,10};
	while(true)
	{
		result=recv(Socket,temp_buffer,30,0);
		if(result!=0&&result!=SOCKET_ERROR)
			receive_buffer=temp_buffer;
	}
	return NULL;
}






class NETWORK
{
public:
     //blah

     Receive();


private:
//blah

     DWORD CALLBACK ThreadedReceive(LPVOID lParam);

};





hmmm. Could it be because a public function is referencing a private function? edit: oh i also get the same message when i use DWORD WINAPI function() as msdn does in its example. [Edited by - Unliterate on September 11, 2004 3:30:39 PM]
Advertisement
your problem is that member functions recieve an explicit pointer to this through the functions arguments. this modifies the functions at compiletime and they won't match the prototype for CreateThread any more. there are several work arounds to this, the most common being making the ThreadedReceive function static, as in :

static DWORD CALLBACK ThreadedReceive(LPVOID lParam);


but then you'll find you will have scope problems with the class variables.
As your leader, I encourage you from time to time, and always in a respectful manner, to question my logic. If you're unconvinced that a particular plan of action I've decided is the wisest, tell me so, but allow me to convince you and I promise you right here and now, no subject will ever be taboo. Except, of course, the subject that was just under discussion. The price you pay for bringing up either my Chinese or American heritage as a negative is - I collect your f***ing head.
Thanks for the responce. I applied the suggestion with moderate succes, I also made all the variables that the threaded function accesses static,and no longer get compile errors but now I get:

error LNK2001: unresolved external symbol "private: static int NETWORK::number_of_connections"

for each of the staticed variables.

I've never used static befor but I followed the msdn example correctly as far as I can tell, the diference being they accessed the static variable outside of the class functions while I am trying to do so inside the class function, is this not doable?

The threaded function will need to access two variables from the class, is there a better way to go about doing this?
A static member variable is like a global variable. You need to define it.

Foo.h
class Foo{  static int Bar; // declaration};

Foo.cpp
#include "Foo.h"int Foo::Bar = 0;
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Ah, thank you both for the quick/accurate help! Now I'm assuming I can still modify these static values within the class function as I would if they were normal class variables (I'm not getting any errors at least). Is this so?
Quote:Original post by Unliterate
Ah, thank you both for the quick/accurate help! Now I'm assuming I can still modify these static values within the class function as I would if they were normal class variables (I'm not getting any errors at least). Is this so?


Yes, though there is only one copy of those static variables, shared by all instances of the class.

The usual idiom for using a non-static member function to start a thread is as follow:

class Foo{   static void trampoline(void *object)   {      static_cast<Foo*>(object)->main();   }public:   void main()   {      // Thread code goes here.   }   void run()   {      _beginthread(&Foo::trampoline, this);   }};


If you're using C run-time functions in the thread, you'll have to use _beginthread instead of CreateThread (if you use CreateThread, you'll have to adjust the declaration of Foo::trampoline accordingly)
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

This topic is closed to new replies.

Advertisement