#### Archived

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

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

## 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)

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 on other sites
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

##### Share on other sites

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

foo::foo()
{
}

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

{
((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 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 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;
// ...

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 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 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

##### Share on other sites
Still rather new to this casting everything-and-it''s-mother business. Can I get some simple syntax on what you mean by
C-style cast?

Webby

##### 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 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.

#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

1. 1
Rutin
67
2. 2
3. 3
4. 4
5. 5

• 21
• 10
• 33
• 20
• 9
• ### Forum Statistics

• Total Topics
633419
• Total Posts
3011787
• ### Who's Online (See full list)

There are no registered users currently online

×