如何使用任意非静态类方法调用AfxBeginThread?也许我可以用boost bind做些什么?以下是Microsoft的预期用法(并且是调用非静态方法的示例,但它是硬编码的方法):
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);
答案 0 :(得分:3)
您需要一个静态函数来传递给AfxBeginThread,但它可以是一个调用对象的非常简单的函数。这是一个可能有效的未经测试的模板函数。
template<class T>
UINT __cdecl StartThread(LPVOID pParam)
{
return ((T*)pParam)->MyThreadProc();
}
答案 1 :(得分:2)
您的代码示例没问题。对于要在单独的线程中调用的每个不同的非静态类方法,您将需要一个线程函数。
boost:bind对你没什么帮助... AfxBeginThread必须是一个C ++模板函数,否则它不能与带有捕获的boost :: bind或C ++ 11 lambdas兼容。
一个替代方案是创建一个结构,其中包含您将拥有的每个类/方法组合的枚举,但这仍然需要您为每个类/方法组合的枚举和回调函数手动添加代码。但是,与为每个类/方法组合创建单独的线程函数相比,它的代码要少得多。
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示例(未经测试):
boost::thread myFooFooThread( boost::bind( &Foo::Foo, myFooObject ) );
答案 2 :(得分:0)
我知道这个问题很古老 - 但它与我目前的情况很接近。我正在研究用Visual Studio 2008项目编写的应用程序,并希望避免所有启动函数。
我发现有两种不同的AfxBeginThread调用:一种需要启动功能(用于启动工作线程);另一个接受来自CWinClass的第一个参数,用于创建用户接口连接对象和工作线程。
我选择第二个选项。这不也适用于上述问题吗?