SDL_QUIT events work with g ++ but not gcc

I want to use SDL from C, not C ++, but I can't seem to get events to work. This code works fine if its a .c or cpp file and is compiled with g ++, also if it's a .cpp file and compiled with gcc. However, if it's a .c file and is compiled with gcc, it compiles just fine, but the SDL_QUIT event doesn't actually do anything, the window just hangs forever.

#include<SDL2/SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 400;


int init();
int loadMedia();
void mainLoop();
void close();

SDL_Window* window =  NULL;
SDL_Surface* screenSurface = NULL;
SDL_Surface* helloWorld = NULL;



int main( int argc, char* args[] ){

  if( !init() ){

printf("Failed to initialize!\n"); 

  }
  else{

if( !loadMedia() ){
    printf("Failed to load media!\n");
}
else{
    mainLoop();

  }
}

  close();

  return 0;

}


void mainLoop(){

  int quit = 0;

  SDL_Event e;

  while( !quit ){

    while( SDL_PollEvent( &e ) != 0 ){
    if(e.type == SDL_QUIT){
        quit = 1;
    }
    }

    SDL_BlitSurface( helloWorld, NULL, screenSurface, NULL);
    SDL_UpdateWindowSurface( window );
  }

}


int init(){

int success = 1;

//initialize sdl
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0){

  printf("SDL could not initialize! SDL_Error: %s\n" , SDL_GetError() );
  success = 0;
}
  else {

//create window
window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );

    if( window == NULL ){
      printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
      success = 0;
    }
    else {
      screenSurface = SDL_GetWindowSurface( window );
    }
  }

  return success;
}


int loadMedia(){

  int success = 1;

  helloWorld = SDL_LoadBMP("images/helloWorld.bmp");
  if( helloWorld == NULL ){
  printf(" Unable to load image %s! SDL_Error: %s\n", "images/helloWorld.bmp", SDL_GetError() );
  success = 0;
  }
  return success;

}


void close(){

//deallocate surface
SDL_FreeSurface( helloWorld);
helloWorld = NULL;

//Destroy window
SDL_DestroyWindow( window );
window = NULL;

//Quit SDL subsystems
SDL_Quit();
}

      

+3


source to share


2 answers


I find your problem incredibly funny and certainly not obvious.

Your problem is caused by the fact that you have a function named close

. This is the POSIX standard name for a function that closes file descriptors. This is contrary to the system function. When called SDL_Init

, it connects to the X server, requests some values, and disconnects (with XCloseDisplay

). XCloseDisplay

, by the way, calls close

on a socket descriptor. The problem is that you have overridden the system close

and yours is called instead, so not only does the socket remain closed, but your code is also called SDL_Quit

, which stops further SDL calls.

With C ++ binding, the function name becomes mangled (mangling is essential for things like function overloading), so its resulting name will be something like _Z5closev

that no longer conflicts with the system function. In fact, you can get the same problematic behavior in C ++ if you add extern "C"

before the function declaration.



A workaround is to either rename your function (it is better not to use standard names), or add a specifier static

before its declaration, which will restrict its binding to only the current translation unit.

The connector does not report a conflict of several definitions, because it is close

marked as a weak symbol (note W

before it):

$ nm -D libc-2.19.so | grep close
# <skiped>
000da660 W close

      

+7


source


It works with me as follows (this is on Mac)

gcc main.c -o test -I/Library/Frameworks/SDL2.framework/Headers  -framework SDL2 

      

Now the actual code is



#include "SDL.h"
#include <stdio.h>

int main(int argc, char* argv[]) {

    SDL_Window *window;                    // Declare a pointer


    // Create an application window with the following settings:
    window = SDL_CreateWindow(
        "An SDL2 window",                  // window title
        SDL_WINDOWPOS_UNDEFINED,           // initial x position
        SDL_WINDOWPOS_UNDEFINED,           // initial y position
        640,                               // width, in pixels
        480,                               // height, in pixels
        SDL_WINDOW_OPENGL                  // flags - see below
    );


    // Check that the window was successfully made
    if (window == NULL) {
        printf("Could not create window: %s\n", SDL_GetError());
        return 1;
    }

    int quit = 0;
    SDL_Event e;

    while( !quit ){

        while( SDL_PollEvent( &e ) != 0 ){
            if(e.type == SDL_QUIT){
                quit = 1;
                printf("Closing the window ...\n");
            }
        }
    }

    SDL_DestroyWindow(window);

    // Clean up
    SDL_Quit();
    return 0;
}

      

Once you close the window, the following message will appear in the terminal

$ gcc main.c -o test -I/Library/Frameworks/SDL2.framework/Headers  -framework SDL2 
$ ./test
Closing the window ...

      

0


source







All Articles