0

私が遭遇した問題は、単純化された FreeGLUT C++ アプリケーション内でのスレッド化のおそらく誤用によって発生します。

をエレガントに終了するglutMainLoop()ことはできないので、私はいくつかの作業を行うことに依存していますが、これはプログラムの機能glutLeaveMainLoop()に制御を戻すものではありません。GL 呼び出しの前に、ヒープ上に作成されたオブジェクト インスタンスへの関数にmain設定されるグローバル ポインターがあります。コールバックmainを使用しないと、このインスタンスでオペレーターを呼び出す人はいませんが、呼び出しの後にそのような操作を配置しました(無益であるため、コメントしました)。atexitdeleteglutMainLoop

これが私がやっていることの疑似コードです(フィルタリングするには長すぎるため、実際のコードは投稿しません):

CWorld* g_world;

AtExit()
{
 delete g_world;
}
void main()
{
  atexit(AtExit);
  // create an instance of an object that creates a thread in its constructor
  // via the new operator and joins this thread in its destructor
  // calling the delete operator on that pointer to the thread instance
  CWidget thisObjectCreatesATinyThread;

  g_world = new CWorld();
  ...
  glutMainLoop();
  // delete g_world;
}

メイン関数には、コンストラクターで作成されたスレッドを介して何らかの作業を行うウィジェット インスタンスも含まれていることに注意してください。このスレッドはそのデストラクタに結合され、メモリは を介し​​て割り当て解除されますdelete

間違った動作: コールバックを設定しないと、オブジェクトatexitのデストラクタが呼び出されないため、リソース リークが発生します。CWorldこのコールバックを設定すると、関数が 1 回しか呼び出されないdeleteにもかかわらず、何らかの理由でオペレーターが 2 回呼び出されます。AtExit

この奇妙な動作の原因を探す場所はどこですか?

CWidget のインスタンス化を無効にしても、依然として独特の動作が得られます。

4

1 に答える 1

1

オリジナルの GLUT ライブラリ (古いものなので) を使用しているのではなく、最も広く普及している GLUT 実装である FreeGLUT を使用していると思います。glutMainLoop() を返すには、次のようにします。

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

glutMainLoop() を呼び出す前に。これにより、glutLeaveMainLoop() を呼び出したときにアクティブな最上位ウィンドウが残っていない場合に戻ります。まだアクティブなウィンドウを気にしない場合は、代わりに次のようにします。

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);

定義を取得するために、おそらく<GL/freeglut.h>代わりに含める必要があります。<GL/glut.h>

于 2012-12-14T16:14:33.587 に答える