5

我正在尝试使用“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 成为我所做的朋友功能:

相机管理器.h

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

相机管理器.cpp

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

我在哪里做错了?

4

3 回答 3

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);
于 2012-08-17T12:55:42.197 回答
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);
}

但是,我建议您开始使用新标准库中的线程支持:

void CameraManager::startDequeuing()
{
    dequeuing = true;
    myThread = std::thread(&CameraManager::dequeueLoop, this);
}
于 2012-08-17T12:52:52.087 回答
2

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

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

于 2012-08-17T12:50:32.453 回答