Sign in to follow this  
spocklogic

atexit and TTF_Quit() problem

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this