When I used to write a thread, I either honestly follow the declaration or use the static member function of the C ++ class as the callback function. The encapsulation is often broken due to the thread code. although I knew the expansion form of class member functions before, I never thought about using it. I learned this trick when I went deep into ATL yesterday :)
The class member method is a special function that is converted to a common function during compilation, for example, a tmyclass class:
Class tmyclass
{
Void func ();
};
This tmyclass: func will eventually be converted to void func (tmyclass * This); that is to say, insert the this pointer to the object itself before the original first parameter.
We can use this feature to write a non-static class member method to directly act as a thread callback function. first look at the definition of the _ beginthread function:
Unsigned long _ rtlentry _ expfunc _ beginthread (void (_ userentry * _ start) (void *), unsigned _ stksize, void * _ Arg );
The first parameter is the callback function used as the thread execution subject. Its prototype is void func (void *). This void * parameter is passed in as custom data. Compare the final form of tmyclass: func mentioned above, which can meet the requirements here.
Now let's do an experiment:
# Include <stdio. h>
# Include <process. h>
Class tmyclass
{
Int m_ncount;
Int m_nid;
Public:
Tmyclass (int nid, int ncount)
: M_nid (NID), m_ncount (ncount)
{}
Void _ userentry threadproc () // class member Method
{
For (INT I = 0; I <m_ncount; I ++) // print a row of numbers based on the m_ncount Member
{
Printf ("Class % d: % d \ n", m_nid, I );
}
}
};
Int main (INT argc, char * argv [])
{
// Federated class, used to convert the class member method pointer to a common function pointer (the compiler has tried not to allow forced conversion between the two functions). I don't know if there is any better method.
Union {
Void (_ userentry * threadproc) (void *);
Void (_ userentry tmyclass: * memberproc )();
} Proc; // although the two function types in the Union now seem very different, their final forms are the same.
Tmyclass myclass1 (), myclass2 (); // two tmyclass objects are generated.
Proc. memberproc = & tmyclass: threadproc; // conversion. Proc. threadproc is the corresponding normal function pointer.
_ Beginthread (Proc. threadproc, 4096, & myclass1); // start thread, Here Proc. threadproc is actually tmyclass: threadproc, And the this pointer it requires is what we give & myclass1.
_ Beginthread (Proc. threadproc, 4096, & myclass2 );
System ("pause ");
Return 0;
}
Run! Magic? :-)
In fact, not only the thread callback function, but as long as the callback function is like func (void *,...), you can use this method to directly use the class member method. (The premise is that the first void * is custom data, that is, it cannot have other functions ).