Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Threads Question

This topic is 5400 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

I have a class that when started will spawn a certain number of threads (depending on input at object istantiation). The class has a function called StartThreads. Inside of there I am calling the CreateThread method. I am having trouble getting CreateThread() to recognize the thread procedure I am passing to it. Here is the function call. cBaseServer::threadProc is of course a member of the class and the function I need the thread to use.
hThreadHandle = CreateThread(NULL, NULL,				        (LPTHREAD_START_ROUTINE)                       
                 &cBaseServer::threadProc, 		         sSharedThreadMemory,NULL, dwThreadID);
threadProc is defined as such
void* Recv(void* vp);
The void* parameter passed to threadProc is just temporary. I have a struct member in the class that I will pass in as a parameter, but I seem to get even more errors when I do not pass a void* to the actual function. I have read that because C++ is so strongly typed that it is difficult (but possible) to create a thread within an object. I know it can be done, I have just not found a snipet of code showing the exact method of casting. Any help on this one? Thanks, Webby

Share this post


Link to post
Share on other sites
Advertisement
That won''t work unless threadProc is static, and perhaps not even then... It will have issues if there is a this pointer being passed implicitly to the threadproc If you''re doing this to make some kind of server that has to receive from multiple clients, have you looked at the select() function? It''s a no-threads way to do it.

--------------------


You are not a real programmer until you end all your sentences with semicolons; (c) 2000 ROAD Programming

You are unique. Just like everybody else.

"Mechanical engineers design weapons; civil engineers design targets."
"Sensitivity is adjustable, so you can set it to detect elephants and other small creatures." -- Product Description for a vibration sensor

Yanroy@usa.com

Share this post


Link to post
Share on other sites

class foo
{
public:
foo();
int EventLoop();
static void ThreadLauncher( void* a_foo );
};

foo::foo()
{
// Hypothetical threading library...
CreateThread( foo::ThreadLauncher, (void*)this )
}

int foo::EventLoop()
{
while( 1 ) { }
}

void foo::ThreadLauncher( void* a_foo )
{
((foo*)a_foo)->EventLoop();
}

The constructer here creates a thread. The two parameters are the initial function for the thread to start in, and a parameter to pass to that function. The constructor chooses to pass a pointer to the object being constructed (this). ThreadLauncher knows that the void* passed is really a foo, so it casts it and then calls EventLoop.

For safety, you could add a dynamic_cast<> to ThreadLauncher() to make sure you''re really looking at a foo*.

Tony

Share this post


Link to post
Share on other sites
I''ve looked at select and it won''t work for what I am trying to do. There has to be a way to do this. Makes no real sense why it wouldn''t be allowed by the language. It''s just a matter of casting correctly.

I''m going to attempt the recommendation above.
Thanks,
Webby

Share this post


Link to post
Share on other sites
The way to do this is to use the lpParameter parameter in the CreateThread function to get back to your object. A little klunky but it works just fine:

Foo* pfoo1, pfoo2;
// ...
CreateThread( ..., ThreadDispatch, reinterpret_cast< LPVOID >(pfoo1), ...);
CreateThread( ..., ThreadDispatch, reinterpret_cast< LPVOID >(pfoo2), ...);

DWORD WINAPI ThreadDipatch( LPVOID lpParameter ) {
Foo* pfoo = reinterpret_cast< Foo* >(lpParameter);

pfoo->YourFunction();
);

At ThreadDispatch(), just cast the parameter back to a Foo and then call the function in the class that you want.

Regards,
Jeff

Edit: Fixed my angle brackets in the cast so they're visible

[edited by - rypyr on August 7, 2003 11:29:40 AM]

Share this post


Link to post
Share on other sites
I'm attempting what you suggested rypyr.
I have

DWORD WINAPI RecvDispatch(LPVOID lpParameter)
{
cBaseServer* pcBaseServer = reinterpret_cast<cBaseServer*>(lpParameter);
pcBaseServer->LocalRecv();
}

and I'm calling CreateThread like this.

CreateThread(NULL, NULL,
RecvDispatch, reinterpret_cast<LPVOID>
(pcBaseServer), NULL, dwThreadID);

It is still giving me this casting error:
error C2664: 'CreateThread' : cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long (__stdcall *)(void *)'

It's got to be something simple at this point.

Webby
[/source]

[edited by - websitewill on August 7, 2003 11:54:45 AM]

Share this post


Link to post
Share on other sites
I know it''s ugly, but I bet a C-style cast would work like a charm reinterpret_cast always drives me nuts...

--------------------


You are not a real programmer until you end all your sentences with semicolons; (c) 2000 ROAD Programming

You are unique. Just like everybody else.

"Mechanical engineers design weapons; civil engineers design targets."
"Sensitivity is adjustable, so you can set it to detect elephants and other small creatures." -- Product Description for a vibration sensor

Yanroy@usa.com

Share this post


Link to post
Share on other sites
He means this:

Blah blah;

void* pVoid = reinterpret_cast< void* >( &blah ); // C++ style cast

is the same as:

void* pVoid = (void*)(&blah); // C-style cast

They do the same thing, but one looks less ugly...

I'm not sure why you're getting that casting error for your dispatch function. It seems to not pick up the WINAPI declaration...

[edited by - rypyr on August 7, 2003 12:32:07 PM]

Share this post


Link to post
Share on other sites
Hmmm, you mention the WINAPI.
I seem to recall having to define something somewhere that is not done correctly in I think winbase.h
I''ll be darned is i can remember what it is.

I think it was this
#define WIN32_WINNT 0x0500#

Someone said tha WIN32_WINNT had to be defined as greater or equal to 0x0500

Maybe this has something to do with it? I remember not getting the hints on that page to work for me so I neglected to stick it in my favorites.

This familiar to anyone?

Webby

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!