Sign in to follow this  

Threaded class functions?

This topic is 4841 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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;

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites

This topic is 4841 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this