windows 使用类成员函数调用 AfxBeginThread?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7852917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Call AfxBeginThread with class member function?
提问by User
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):
如何使用任意非静态类方法调用 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);
回答by Mark Ransom
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.
您将需要一个静态函数来传递给 AfxBeginThread,但它可以是一个调用对象的非常简单的函数。这是一个可能有效的未经测试的模板函数。
template<class T>
UINT __cdecl StartThread(LPVOID pParam)
{
return ((T*)pParam)->MyThreadProc();
}
回答by smerlin
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.
boost:bind 对你没有任何帮助...... AfxBeginThread 必须是一个 C++ 模板函数,否则它不能与 boost::bind 或带有捕获的 C++11 lambdas 兼容。
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 ) );
回答by Charles Thomas
I know this question is pretty old -- but it's close to my current situation. I am working on an application written in Visual Studio 2008 project, and would like to avoid all the start functions.
我知道这个问题已经很老了——但它接近我目前的情况。我正在开发用 Visual Studio 2008 项目编写的应用程序,并希望避免所有启动功能。
What I found is there are two different invocations of AfxBeginThread: One requires the start function (for launching working threads); the other takes, as its first parameter a class derived from CWinClass and is used for creating User Interface connected objects AND worker threads.
我发现 AfxBeginThread 有两种不同的调用:一种需要 start 函数(用于启动工作线程);另一个以从 CWinClass 派生的类作为其第一个参数,用于创建用户界面连接对象和工作线程。
I am choosing the second option. Would this not also work in the above question?
我选择第二个选项。这在上述问题中也行不通吗?