atexit and TTF_Quit() problem

Started by
2 comments, last by SiCrane 15 years, 6 months ago
I keep having problems with atexit( TFF_Quit ) running before some class destructors. The class destructor uses TTF_CloseFont(), so this results in an error. For example:
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <vector>

class Font {
public:
	~Font();

	TTF_Font *font;
};

Font::~Font() 
{
	// Access violation here
	TTF_CloseFont( font );
}

std::vector<Font> fonts;

int main( int argc, char **argv )
{
	if( SDL_Init( SDL_INIT_VIDEO ) < 0 || TTF_Init() < 0 ) {
		return 1;
	}

	atexit( SDL_Quit );
	atexit( TTF_Quit );

	SDL_Surface *screen = SDL_SetVideoMode( 640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF );

	fonts.resize( 1 );
	fonts[ 0 ].font = TTF_OpenFont( "c:\\windows\\fonts\\times.ttf", 12 );

	return 0;
}
TTF_Quit keeps running (I think) before the Font destructor is called. Is there any way around this, or better yet, a way to force atexit() to execute last?
Advertisement
One way would be to create a global object that calls TTF_Quit() in its destructor and define it above the fonts object. This would guarantee that the fonts destructor would be called first. However, you should really look into getting rid of the global.
Quote:Original post by SiCrane
One way would be to create a global object that calls TTF_Quit() in its destructor and define it above the fonts object. This would guarantee that the fonts destructor would be called first. However, you should really look into getting rid of the global.


In a project with multiple source files, would there be any way to ensure that the class destructor with TTF_Quit() will be the last to execute?

I know global variables are generally frowned upon in C++, but there is no easy way that I can think of to get around my problem. Five functions in one file need access to the variable, but there's no way for them to share it unless I make a parameter in each function, which would mean my main program would have to keep track of the variable. But I'm writing this particular code to be self-sufficient and easy to use so I can use it in future projects. I could take out four functions as they are not absolutely necessary, but I would still have to use a static variable which will cause the same problem as using the global.

I guess I could use dynamic memory, unless someone knows a better way.
Quote:Original post by spocklogic
In a project with multiple source files, would there be any way to ensure that the class destructor with TTF_Quit() will be the last to execute?

Not in standard C++. Something you can do is place a global in each and every one of your source files at the top each of which increments a shared counter upon construction. Then when each one is destroyed have the decrement the counter. The one that brings it down to zero can call TTF_Quit().

However, this kind of thing can still get screwed up if you forget it even in one source file or put something that depends on SDL_TTF before any of the constructors, etc. On the whole it'd probably be safer to eliminate the global.

This topic is closed to new replies.

Advertisement