We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

Create a thread in a class

mikechen
mikechen asked
on
Medium Priority
374 Views
Last Modified: 2013-12-03
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
Comment
Watch Question

Commented:
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..

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

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

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

Author

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.

Commented:
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.

Author

Commented:
Thank you very much, Juan.

I really appreciate your help.

Mike

Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.