无法在pthread_create函数中将' * void(MyClass :: *)(void *)转换为void *(*)(void *)

时间:2012-08-17 12:44:53

标签: c++ pthreads friend friend-function

我正在尝试使用类“CameraManager”创建一个新线程,但我有以下错误:

  

无法在pthread_create函数中将'* void(CameraManager :: *)(void *)转换为void *(*)(void *)

我在cameramanager.h文件中定义:

public:
void *dequeueLoop(void *ptr);

并在cameramanager.cpp

void CameraManager::startDequeuing(){
dequeuing = true;
dequeueThreadId = pthread_create(&dequeueThread, NULL, &CameraManager::dequeueLoop, NULL);
}

void *CameraManager::dequeueLoop(void *ptr){
while(dequeuing){
    highSpeedCamera->dequeue();
    highSpeedCamera->enqueue();
}

我不想将dequeueLoop声明为静态函数我也尝试以下列方式将dequeueLoop声明为类友元函数但是它没有类变量'highSpeedCamera'和'dequeuing'的范围和编译器还告诉我'dequeueLoop'未在此范围内声明

使dequeueLoop成为朋友的功能我做了:

cameramanager.h

public:
friend void *dequeueLoop(void *ptr);

cameramanager.cpp

void CameraManager::startDequeuing(){
    dequeuing = true;
    dequeueThreadId = pthread_create(&dequeueThread, NULL, &CameraManager::dequeueLoop, NULL);
}
void *dequeueLoop(void *ptr){
    while(dequeuing){
        highSpeedCamera->dequeue();
        highSpeedCamera->enqueue();
    }
}

我做错了什么?

3 个答案:

答案 0 :(得分:7)

  

我不想将dequeueLoop声明为静态函数

如果你想使用pthreads,那么你需要一个入口点的静态或非成员函数。您可以将指向对象的指针传递给此函数,将其用作非静态成员函数的蹦床:

static void * dequeueEntry(void * self) {
    return static_cast<CameraManager*>(self)->dequeueLoop();
}

dequeueThreadId = pthread_create(
    &dequeueThread, NULL, 
    &CameraManager::dequeueEntry, // <-- pointer to trampoline function
    this);                        // <-- pointer to object for member function

或者,如果您有一个现代编译器,则可以使用标准线程库:

std::thread thread(&CameraManager::dequeLoop, this);

答案 1 :(得分:3)

如果您希望该函数成为该类的成员,则必须static。这是因为线程函数将被直接调用,并且没有有效的this指针。这可以通过使用包装函数来解决,该函数将传递给实际对象,然后调用正确的成员函数:

void *dequeueLoopWrapper(void *p)
{
    CameraManager *cameraManager = static_cast<CameraManager*>(p);
    camereraManager->dequeueLoop();
    return nullptr;
}

// ...

void CameraManager::startDequeuing()
{
    dequeuing = true;
    dequeueThreadId = pthread_create(&dequeueThread, NULL, dequeueLoopWrapper, this);
}

但是,我建议您开始使用新标准库中的threading support

void CameraManager::startDequeuing()
{
    dequeuing = true;
    myThread = std::thread(&CameraManager::dequeueLoop, this);
}

答案 2 :(得分:2)

除非它是静态的,否则不能将指向成员函数的指针用作函数指针。你必须让dequeueLoop成为一个自由函数,或者写一个免费函数作为它的包装。

要在自由函数中访问类成员,您应该让函数将它的this指针作为pthread_create的最后一个参数传递。然后让free函数将它的参数转换为指向类的指针。