Tony The Lion
Tony The Lion

Reputation: 63200

Strange C++ thread function invocation

I have the following:

   class DThread
   {
      virtual void run()=0;

    _beginthreadex(NULL,0,tfunc,this,0,&m_UIThreadID);  // class itself being passed as param to thread function...

    static unsigned int __stdcall tfunc(void* thisptr) 
        {
            static_cast<DThread*>(thisptr)->run();
            return 0;
        }

//other stuff

}

The run function is implemented in a derived class.

Why is the function that's being called in the thread being called through a cast this pointer? Is this good practise?

Can't it just be called directly?

The actual function needing to run is in the derived class.

My question is

Upvotes: 4

Views: 235

Answers (4)

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84179

Most platform-level thread APIs are bare-bones C and take a plain pointer to function to run in new thread. This means in C++ that function has to be either a free function or a static member. Neither of these give access to any class instance. The workaround for building statefull thread classes is to exploit additional "pass-through" argument of the thread creation call (that's usually a pointer that is later passed to the function executed in the new thread) and give it a pointer to the class itself, i.e. this. The static function could then call a [virtual] member, say run() or something like that.

Upvotes: 2

nos
nos

Reputation: 229118

_beginthreadex expects a (stdcall) C style function, it cannot use a C++ member function as it has no knowledge of C++. The way to get a member function running is to pass a pointer to an object and call the member function inside that function. Such a function is often called a trampoline.

Upvotes: 4

jopa
jopa

Reputation: 1139

The _beginthreadex function is a C-function. It doesn't know anything about C++. To access a C++ member from within the thread function you need to cast it.

Upvotes: 1

Anthony
Anthony

Reputation: 12397

Thread functions are not 'class-aware'. Your implementation makes them class aware so that the derived 'run' function will have access to class members.

Upvotes: 3

Related Questions