Archived

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

Creating a thread from within a class

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

Hi, For a project I''m working on, I''m trying to write time-keeping code that keeps track of time within the app. I am encapsulating all this into a class. Well, I am having trouble getting my thread to start from within my member function. Here is the code i got:
  
void CTimeKeeper::StartClock()
{
	bActive = true;
	hClock = CreateThread(NULL, NULL, ThreadRouter, this, NULL, &clockId);
}

unsigned long _stdcall CTimeKeeper::ThreadRouter(void* mydata)
{
	CTimeKeeper *ptr = (CTimeKeeper*)mydata;

	(CTimeKeeper *)mydata->ClockThread();	
}

  
Anyway.. I get the error "error C2227: left of ''->ClockThread'' must point to class/struct/union". Shouldn''t the typecast take care of that? Just a little confused.. thanks

Share this post


Link to post
Share on other sites
Methods are functions that take a hidden parameter (the ''this'' pointer). So the signiture of your method does not match the requeisite signiture of the CreateThreadEx (or _beginthreadex) API calls.

The method must be declared static (means no ''this'' pointer is passed in, and consequentially means you can''t use ''this'' in static methods). The create thread calls have a void* that you can pass the this pointer through to the thread function.

Share this post


Link to post
Share on other sites
you don''t have to use a static method, you know.

  
struct Thread {
DWORD APIENTRY ThreadProc();
};
CreateThread(..., (LPTHREAD_START_ROUTINE) Thread::ThreadProc, &aThreadInstance, ...);

i didn''t test this, but it _should_ work.

---
Come to #directxdev IRC channel on AfterNET

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
Test it, because it won''t. It *may* compile (though any self-respecting compiler should raise hell with that cast), but it definitely won''t execute as expected.

i assumed it will work because i believe that''s exactly how COM works. would you mind explaining why it (theoretically) will not work?

and who knew msvc didn''t like casts? but that''s what we have unions for. this code is working "as expected", meaning it prints

Writing junk... 100


  
struct Thread {
Thread() {
junk = 100;
}

DWORD APIENTRY ThreadProc() {

// accessing instance data here

wsprintf(buf, "Writing junk... %d\n", junk);
OutputDebugString(buf);

return 0;
}

private:
int junk;
char buf[100];
};

// msvc doesn''t like casts, so there

union Converter {
unsigned long (__stdcall Thread::*Member)(void);
LPTHREAD_START_ROUTINE Proc;

Converter(unsigned long (__stdcall Thread::*m)(void)) {
Member = m;
}

operator LPTHREAD_START_ROUTINE() {
return Proc;
}
};

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
Thread th;
DWORD id;
HANDLE hThread = CreateThread(0, 0, Converter(&Thread::ThreadProc), &th, 0, &id);

Sleep(100);

CloseHandle(hThread);

return 0;
}

i really don''t see anything wrong with such usage.

---
Come to #directxdev IRC channel on AfterNET

Share this post


Link to post
Share on other sites