Call AfxBeginThread with class member function?
Solution 1
You will need a static function to pass to AfxBeginThread, but it can be a very simple function that calls into the object. Here's an untested template function that might work.
template<class T>
UINT __cdecl StartThread(LPVOID pParam)
{
return ((T*)pParam)->MyThreadProc();
}
Solution 2
Your code sample is fine. You will need a thread function for each different non-static class method you want to call in separate threads.
boost:bind will not help you whatsoever... AfxBeginThread would have to be a C++ template function, otherwise it cant be compatible with boost::bind or C++11 lambdas with captures.
One Alternative is to create a struct, with an enum for each class/method combination you will have, but this still requires you to manually add code to both the enum and the callback function for each class/method combination. However its not that much less code than creating a separate thread function for each class/method combination.
struct ThreadData
{
LPVOID object;
enum ObjectCallType {
Foo_Foo,
Foo_Bar
} objectCallType;
LPVOID* param;
ThreadData( LPVOID pobject, ObjectCallType poct, LPVOID* pparam=0 )
:object(pobject), objectCallType(poct), param(pparam) {}
};
UINT MyThreadProc( LPVOID pParam )
{
TheadData* thData = (ThreadData*)pParam;
try
{
switch( thData->objectCallType )
{
case ThreadData::Foo_Foo:
Foo* foo = (Foo*)thData->object;
foo->foo();
break;
case ThreadData::Foo_Bar:
Foo* foo = (Foo*)thData->object;
foo->bar( thData->param );
break;
default:
throw std::exception("unhandled method call type");
}
}
catch( std::exception& e )
{
std::cerr << e.what() << std::endl;
delete thData;
return 1;
}
delete thData;
return 0;
}
//usage:
AfxBeginThread(MyThreadProc, new ThreadData(myFooObject,ThreadData::Foo_Bar,myFooCallParam));
Boost example (untested):
boost::thread myFooFooThread( boost::bind( &Foo::Foo, myFooObject ) );
User
Updated on June 13, 2022Comments
-
User almost 2 years
How can I call AfxBeginThread with an arbitrary non-static class method? Maybe there is something I can do with boost bind? Below is the expected usage from Microsoft (and is an example of calling a non-static method but it is hard-coded which method):
UINT MyThreadProc( LPVOID pParam ) { CMyObject* pObject = (CMyObject*)pParam; if (pObject == NULL || !pObject->IsKindOf(RUNTIME_CLASS(CMyObject))) return 1; // if pObject is not valid // do something with 'pObject' return 0; // thread completed successfully } // inside a different function in the program ... pNewObject = new CMyObject; AfxBeginThread(MyThreadProc, pNewObject);