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をフレンド関数にするために:

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();
    }
}

私はどこで間違っているのですか?

4

3 に答える 3

7

dequeueLoop静的関数として宣言したくない

pthreadを使用する場合は、エントリポイントに静的関数または非メンバー関数が必要です。非静的メンバー関数へのトランポリンとして使用して、オブジェクトへのポインターをこの関数に渡すことができます。

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の最後の引数として関数にポインタを渡す必要があります。次に、free関数に、その引数をクラスへのポインターにキャストさせます。

于 2012-08-17T12:50:32.453 に答える