Задать вопрос
@viktorokh96
Student, programmer

Что не так с библиотекой SDL 2.0 на С?

Прошу помощи у знатоков SDL.
Предисловие. Недавно я получил от преподавателя задание на Си, в котором мне необходимо было, средствами библиотеки SDL,
нарисовать график в полярных координатах. Всё бы хорошо, если бы не
сильная ограниченность туториалов по SDL 1.2 или SDL 2.0 на
чистом Си (!) . Все примеры и статьи которые я находил
были на С++.
На одном из таких туториалов "lazyfoo.net/tutorials/SDL/03_event_driven_programm..."
предлагается использовать обработку событий, для того что бы приложение
реагировало на некоторые запросы пользователя. Например нам необходимо
сделать так, что бы окно приложения закрывалось при нажатии кнопки. В
таком случае событие от нажатия кнопки приходит в очередь событий, и оно
в свою очередь может быть извлечено оттуда функцией int SDL_PollEvent ( SDL_Event *e )
Эта функция возвращает 0 если очередь событий пуста и 1 если какие-либо
события ожидают своей обработки в очереди.
Так вот... Программа работает отлично на С++ и работает не корректно под Си. Проблема в том что вышеуказанная функция выдачи события на Си возвращает всегда 0, в независимости от того что я делаю, тоесть говорит о том что очередь событий пуста. В программе скомпилированной под С++ таких проблем нет... Странно, не так ли? Не работает в программе ,скомпилированной на Си, трюк с явной подачей события с помощью int SDL_PushEvent(SDL_Event *e)
Тогда как в С++ это всё прекрасно пашет.
Проблема усугубляется тем, что по сути программа на Си и на С++ обращаются к одной и той же библиотеке, ведь SDL - динамическая и она одна общая на двоих. Как то замешан компилятор???
Кстати по этой проблеме уже обращались и другие люди: "stackoverflow.com/questions/31234536/no-response-f..." , но внятного ответа на других форумах я так и не нашёл.

Моя программа целиком:
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_events.h>
//#include <stdlib.h>
//#include <math.h>
//#include <time.h>

#define IMAGE_DIR "./hello_world.bmp"

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

//The window we'll be rendering to 
SDL_Window* gWindow = NULL;

//The surface contained by the window 
SDL_Surface* gScreenSurface = NULL; 

//The image we will load and show on the screen 
SDL_Surface* gHelloWorld = NULL;

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

int main(int argc, char const *argv[])
{
  int quit = 0; //  Main loop flag

  SDL_Event e;  // Event handler

  if(SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) printf("Error events\n");

  if (init()) {
    printf( "Failed to initialize!\n" );
    return 1;
  }
  
  if(loadMedia()) {
    printf( "Failed to load media!\n" );
    return 1;
  }

  while (!quit) {
    //Hanle events on queue 
    while( SDL_PollEvent( &e ) != 0) {
      // User requests quit
      printf("Debug\n");
      if (e.type == SDL_QUIT) {
        quit = 1;
      }
    }
    //Apply the image 
    SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

    //Update the surface 
    SDL_UpdateWindowSurface( gWindow );
  }

  //Free resources and close SDL
  close();

  return 0;
}


int init()
{
  if (SDL_Init(SDL_INIT_VIDEO) < 0)
  {
    printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
    return 1;
  }

  //Create window
  gWindow = SDL_CreateWindow( " SDL Tutorial", 
                              SDL_WINDOWPOS_UNDEFINED, 
                              SDL_WINDOWPOS_UNDEFINED, 
                              SCREEN_WIDTH, 
                              SCREEN_HEIGHT, 
                              SDL_WINDOW_SHOWN);
  if(gWindow == NULL ) {
     printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
     return 1;
  }

  //Get window surface
  gScreenSurface = SDL_GetWindowSurface( gWindow );

  return 0;
}


int loadMedia()
{
  //Load splash image 
  gHelloWorld = SDL_LoadBMP( IMAGE_DIR );
  if (gHelloWorld == NULL) {
    printf( "Unable to load image %s! SDL Error: %s\n", IMAGE_DIR , SDL_GetError() );
    return 1;
  }

  return 0;
}

void close()
{
  //Deallocate surface
  SDL_FreeSurface ( gHelloWorld );
  gHelloWorld = NULL;

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

  //Quit SDL subsystems 
  SDL_Quit();
}


Самый важный фрагмент кода:

while (!quit) {
    //Hanle events on queue 
    while( SDL_PollEvent( &e ) != 0) {
      // User requests quit
      printf("Debug\n");
      if (e.type == SDL_QUIT) {
        quit = 1;
      }
    }
    //Apply the image 
    SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

    //Update the surface 
    SDL_UpdateWindowSurface( gWindow );
  }


Здесь то и кроется проблема... Кто знает? Как сделать так, что бы эта вещь заработала в программе на Си?
Опции компиляции: сс graphictest.c -lSDL2 -g -o graphic

P.S Да написать программу нужно именно на Си, таково условие задачи.
  • Вопрос задан
  • 903 просмотра
Подписаться 1 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
@viktorokh96 Автор вопроса
Student, programmer
UPD: После многочасовых нервосрывов задача была решена очень тривиально. функцию close стоит переименовть на что нибудь другое, например closeWin(), в таком случае наша программа не будет переопределять эту, уже определенную функцию в подключенных библиотеках. В С++ это всё работало, видимо, именно потому что, что есть пространства имен и другие фичи по скрытию имен. Впервые на такие грабли наступаю и никому такого не пожелаю.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы