SDL_QUIT事件适用于g ++但不适用于gcc

Man*_*iru 3 c gcc sdl sdl-2

我想将SDL与C而不是C++一起使用,但我无法使事件发挥作用.如果它是一个.c或cpp文件并使用g ++编译,如果它是.cpp文件并使用gcc编译,则此代码可以正常工作.但是,如果它是一个.c文件并使用gcc编译它编译得很好,但SDL_QUIT事件实际上并没有做任何事情,窗口就会永远挂起.

#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();
}
Run Code Online (Sandbox Code Playgroud)

kel*_*tar 7

我觉得你的问题非常有趣,肯定不是很明显.

你的问题是由你的名字功能引起的close.这是关闭文件描述符的函数的标准POSIX名称.它与系统功能冲突.当SDL_Init被调用时,它连接到X服务器,查询一些值,并断开(含XCloseDisplay).XCloseDisplay除其他外,调用close其套接字描述符.问题是,你已经覆盖了系统close,而你的系统被调用了 - 所以不仅套接字保持未闭合,而且SDL_Quit还被你的代码调用,这会阻止任何进一步的SDL调用.

使用C++链接时,函数名称会被破坏(对于像函数重载这样的事情,修改是必不可少的),因此它的结果名称就像是_Z5closev,它不再与系统函数冲突.事实上,如果你extern "C"在函数声明之前添加,你可以在C++中获得相同的问题行为.

解决方法是重命名您的函数(最好不要使用标准名称),或者static在声明之前添加说明符,这将限制其仅与当前翻译单元的链接.

链接器不报告多个定义冲突,因为close标记为弱符号(W在它之前注释):

$ nm -D libc-2.19.so | grep close
# <skiped>
000da660 W close
Run Code Online (Sandbox Code Playgroud)