2015-01-11 2 views
3

C++ 대신 C에서 SDL을 사용하고 싶지만 작동 할 이벤트를 얻을 수 없습니다. 이 코드는 .c 또는 cpp 파일이 완벽하게 작동하며 .cpp 파일이고 gcc로 컴파일 된 경우 g ++로 컴파일됩니다. 그러나 .c 파일이고 gcc로 컴파일 된 경우 잘 컴파일되지만 SDL_QUIT 이벤트는 실제로 아무 것도하지 않습니다. 창이 영원히 멈 춥니 다.SDL_QUIT 이벤트는 g ++에서 작동하지만 gcc에서는 작동하지 않습니다.

#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(); 
} 
+1

코드는 잘못이 아니다. QUIT 이벤트를 만들기 위해 어떤 작업을 수행합니까? 문제에 대한 완전한 편집 가능한 최소 예를 작성하고 질문에 포함하십시오. – keltar

+0

창에서 X 버튼을 클릭해도 아무런 효과가 없습니다. 또한 다른 키 또는 마우스 이벤트를 추가하면 순수 C에서는 작동하지 않지만 C++ 컴파일러 또는 소스 코드 결과로 전환하면 모든 sdl 이벤트가 올바르게 작동합니다. – Manjiru

+1

완전한 예제를 게시하지 않으려는 경우 질문에 답할 수 없습니다. – keltar

답변

7

믿을 수 없을 정도로 재미 있고 확실한 문제가 아닌지 확인하십시오.

이름이 close 인 기능 때문에 문제가 발생했습니다. 이것은 파일 디스크립터를 닫는 함수의 표준 POSIX 이름이다. 시스템 기능과 충돌합니다. SDL_Init이 호출되면 X 서버에 연결되고 일부 값을 쿼리하고 연결을 끊습니다 (XCloseDisplay). XCloseDisplay은 무엇보다도 소켓 설명자에서 close을 호출합니다. 문제는 시스템 close을 재정의하고 대신 사용자가 호출했기 때문에 소켓뿐만 아니라 닫히지 않고 코드에 의해 SDL_Quit도 호출되어 더 이상 SDL 호출을 중지합니다.

C++ 링키지에서는 함수 이름이 맹 글링됩니다 (함수 오버로딩과 같은 경우에는 mangling이 필수적이므로) 결과 이름은 시스템 기능과 더 이상 충돌하지 않는 _Z5closev과 같습니다. 사실, 함수 선언 전에 extern "C"을 추가하면 C++에서 동일한 문제가있는 동작을 얻을 수 있습니다.

해결 방법은 함수 이름을 바꾸거나 (표준 이름을 사용하지 않는 것이 좋습니다)지정자를 선언 전에 추가하면 현재 연결 단위 만 연결되도록 제한됩니다. close가 표시되어 있으므로 약한 심볼 (그 전에 W주의)로

링커는 여러 정의가 충돌을보고하지 않습니다 문제

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

당신의 대답이 나를 도왔다 - 고마워! 우리가 사용하는 튜토리얼은 다음과 같습니다. http://lazyfoo.net/tutorials/SDL/03_event_driven_programming/index.php – Rachael

+0

나는 왜 내가 seg fault를 얻었는지 이해할 수 없었고, 나는 이것을 생각하지 못했다고 믿을 수 없습니다. facepalm (키보드) 감사합니다! – nephi12

0
다음과 같이 나와 함께 일하고

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

이제 실제 코드는 당신이 창을 닫으되면

#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; 
} 

는, 다음과 같은 메시지가 나타납니다입니다 (이것은 맥에) 터미널

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