0

関数を GLUT コールバック glutSpecialFunc に渡そうとしています。

静的関数(specialKeyProcessor)を渡そうとすると、完全に機能します。

この関数をキーボード関連の関数の処理に特化したクラス (KeyBoardMovement) に移動すると、機能しないようです。

.... キーボード移動キーボード; .... glutSpecialFunc(keyboard.specialKeyProcessor);

エラーが表示されます:非静的メンバー関数への参照を呼び出す必要があります。

異なる場所に配置された同じ関数の違いが見られないため、このエラーを理解できません。

4

2 に答える 2

2

このglutSpecialFunc関数は、ウィンドウごとのコールバックを設定します。OpenGLUT を使用している場合は、 を使用して各ウィンドウにデータを関連付けることもできますglutSetWindowData

したがって、次のようにグローバル shim 関数を作成できます。

void specialKeyProcessor(int key, int x, int y) {
    KeyboardMovement *keyboard = static_cast<KeyboardMovement *>(glutGetWindowData());
    keyboard->specialKeyProcessor(key, x, y);
}

次を使用してキーボードハンドラーを関連付けますglutGetWindowData

glutSetWindowData(static_cast<void *>(&keyboard));

複数のウィンドウ データを格納する必要がある場合はstruct、各ウィンドウ固有データのフィールドを持つウィンドウ固有へのポインターを格納できます。


OpenGLUT を使用していない場合は、std::mapウィンドウ ID をグローバル データにマッピングすることを検討できます。次に、上記と同様のアプローチを使用して、ウィンドウ固有のデータを取得できます。

于 2013-02-13T23:49:13.980 に答える
0

C ++はクロージャをサポートしていません。つまり、クラスインスタンスを、メソッドとともに、呼び出されたときにクラスインスタンスのメソッドを実行する関数ポインタに変換することはできません。

残念ながら、GLUTは、他のほとんどのCコールバックAPIがサポートしているように、データ対応コールバックをサポートしていません。つまり、クラスのグローバルインスタンスを呼び出すラッパー関数を作成するか、実行時に新しい関数を実際に作成できる「ffcall」と呼ばれるライブラリを使用して、非常に汚いトリックを使用します。 GLUTに渡すことができるクロージャ。しかし、それは本当に暗いことであり、正しいことはGLUTを捨てることです。

于 2013-02-13T23:40:29.217 に答える