• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 360
  • Last Modified:

Create a thread in a class

I am using VC++5.0 in NT.

I want to create a thread in a class when a public function of this class is called. The start address of this thread is  one of the member function of this class. Like this:

class  MyClass
{
    void  Startup();
    void  ThreadRountine();
};



void MyClass::Startup()
{
    ...
    ::CreateThread(..., ThreadRountine, ...);
    ...
};

But I fail to compile this code. Only when the ThreadRountine is a global function, then it is OK.

Is this doable or I miss something here ?

Thanks in advance.

Mike
0
mikechen
Asked:
mikechen
  • 3
  • 3
1 Solution
 
jilangCommented:
Yes, it's doable, but the problem is that your ThreadRoutine must either be a global function or a static member function.  I can give you the nitty-gritty C++ details on why if you like, but these are your options.  Note that as a static member function it behaves an awful lot like a global function.  If you need it to access member data of a particular object, you'll need to pass along a pointer to the object as the argument to be passed to ThreadRoutine, e.g. your this pointer.
More details available on request..
0
 
mikechenAuthor Commented:
Yes. Please send me some more information in detail. You can e-mail me if you would.  (mikechen@fbcs.fujitsu.com)

Thanks in advance.

Mike

0
 
jilangCommented:
You may or may not be aware that every normal member
function in C++ has an extra, hidden parameter, a "this"
pointer.  For instance, if you have

class Class {
   int foo;
   int Bar1() {return foo;}
   int Bar2() {return this->foo;}
};

You can refer to foo either by name, as in Bar1, or by
dereferencing the this pointer, as in Bar2.  The this
pointer is a Class * inserted as a hidden, first parameter
to Bar1 and Bar2.

Now for static member functions.  Static member functions
are meant to operate on the class itself, not on any
particular object.  Therefore they do not have any extra
parameters.

The CreateThread routine takes a function pointer to a
function with a normal C prototype, something like
void (*threadFunc)(void *lpVoid).  Normal member functions
can't be used, because CreateThread will not know to
insert a this pointer, nor will the operating system.
Static member functions, on the other hand, do not have
any hidden parameters and will work fine.

So the questions becomes, how do you get the thread routine
to work on the data of a particular object?  The answer is
via the void * parameter to the thread routine.  
Extending the above example,

class Class {
   int foo;
   int Bar1() {return foo;}
   int Bar2() {return this->foo;}
   static void ThreadRoutine(void *);
};

void Class::ThreadRoutine(void *lpVoid)
{
   Class *myThis = (Class *)lpVoid;

   myThis->foo;
}

The thread routine accepts one parameter, a void *.  This
argument is passed to CreateThread; when calling CreateThread,
pass in this as your parameter.  ThreadRoutine then must
cast the void * it receives into a Class *.  It then may
operate on member data, but only through the cast pointer.

Admittedly, this is not the most elegant looking code in
the world.  Another option is to have a ThreadRoutine which
is a normal member function, as in your example, and another
static member function which casts its argument and calls
ThreadRoutine on the object.

Hope this answers your question.  Let me know if you need
additional explanation on any part of this.
--Juan
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
mikechenAuthor Commented:
Thank you very much, Juan.

Two more things:

1. What will be the 3rd parameter in CreateThread() if I declare ThreadRountine() as a static member function?
I got an error:
"error C2664: 'CreateThread' : cannot convert parameter 3 from 'void (void)' to 'unsigned long (__stdcall *)(void *)"

2. Global function and static member function, which one is better ?

Thanks in advance.

Mike

2.
0
 
jilangCommented:
1.  This is because your static thread function does not have the same prototype as required.  It should be declared,
   long __stcall ThreadRoutine(void *);

2.  I prefer static member function; global function works about the same, a static member function has the added benefit of access protection if desired.

Hope this helps.
0
 
mikechenAuthor Commented:
Thank you very much, Juan.

I really appreciate your help.

Mike

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now