我有一个问题,在课堂上,我有这个方法:virtual void start(void *(*ptr)(void*), void *);
在另一个方面,我想用这个方法调用:void *Room::run(void *p)
。
所以我尝试这样做:thread->start(&Room::run, 0);
但是编译器不想要它,因为:cannot convert parameter 1 from 'void *(__thiscall Room::* )(void *)' to 'void *(__cdecl *)(void *)'
我该如何解决?模板?还是有更明显的解决方案?
谢谢 !
P.S:准确地说,我需要它来制作线程(http://linux.die.net/man/3/pthread_create)。
答案 0 :(得分:3)
在C ++中,指向(独立)函数和指向方法的指针是完全不同的动物,不能混合。
如果要将指向成员函数的指针传递给需要指向函数指针的API,那么典型的解决方案是使用一个小的包装函数:
class Room {
public:
void run();
// other members omitted
// wrapper function
static void* run_wrapper(void* p)
{
static_cast<Room*>(p)->run();
return NULL;
}
};
你这样使用它:
thread->start(Room::run_wrapper, myRoomPointer);
答案 1 :(得分:0)
我强烈建议不要将一个函数指针强制转换为void *
指针,因为在c ++和c中,大小可能不同。
总的来说,你的解决方案不是很好的c ++。不可否认,使用c库会让它变得有点棘手。这是我在当前项目中使用的方法: -
class ThreadBase
{
public:
ThreadBase ()
{
}
virtual ~ThreadBase ()
{
// TODO - inform thread to stop, using a message or a signal or something
// and then wait for the thread to terminate
void
*return_value = 0;
pthread_join (m_thread_handle, &return_value);
}
void Run ()
{
if (pthread_create (&m_thread_handle, 0, ThreadFunction, this))
{
// error - throw an exception or something
}
}
private:
static void *ThreadFunction (void *param)
{
ThreadBase
*thread = static_cast <ThreadBase *> (param);
thread->Main ();
return 0;
}
virtual void Main () = 0;
private:
pthread_t
m_thread_handle;
};
然后从ThreadBase派生特定于实现的版本:
class SomeThread : public ThreadBase
{
private:
void Main ()
{
// do something
}
};
您可能希望更改Main
以返回退出代码并将其从该线程传回。如果它处于无限循环中,你需要一种让Main
退出的方法(例如,如果它是一个使用某种消息的监听器)。