【问题标题】:SDL event handling not workingSDL 事件处理不起作用
【发布时间】:2015-07-17 18:10:05
【问题描述】:

我目前正在通过阅读 Lazy foo 教程来学习 SDL。我在 Linux 上使用代码块 13.12。我无法让事件处理正常工作。

我基本上是在尝试显示一张图片(效果很好),但是无论我点击关闭按钮多少次,它都不会关闭

代码:

#include <SDL2/SDL.h>
#include <stdio.h>
//Declaring the main window, the main surface and the image surface
SDL_Window *window = NULL;
SDL_Surface *scrsurface = NULL;
SDL_Surface *imgSurface = NULL;
SDL_Event event;
int run = 1;

//The function where SDL will be initialized
int init();
//The function where the image will be loaded into memory
int loadImage();
//The function that will properly clean up and close SDL and the variables
int close();

//The main function
int main(void){
    if(init() == -1)
        printf("Init failed!!!");
    else{
        if(loadImage() == -1)
            printf("loadImage failed!!!");
        else{

            //Displaying the image

            while(run){
                //Event handling
               while(SDL_PollEvent(&event)){
                    switch(event.type){
                        case SDL_QUIT:
                            run = 0;
                            fprintf(stderr, "Run set to 0");
                            break;
                        default:
                            fprintf(stderr, "Unhandled event");
                         break;
                    }
                } 
                //Blitting nad updating
                SDL_BlitSurface(imgSurface, NULL, scrsurface, NULL);
                SDL_UpdateWindowSurface(window);
            }
        close();

        }
    }
    return 0;

}

int init(){
 if(SDL_Init(SDL_INIT_VIDEO) < 0)
    return -1;
 else{
    window = SDL_CreateWindow("SDL_WINDOW", SDL_WINDOWPOS_UNDEFINED,  SDL_WINDOWPOS_UNDEFINED, 900, 900, SDL_WINDOW_SHOWN);
    if(window == NULL)
        return -1;
    scrsurface = SDL_GetWindowSurface(window);

}
return 0;
}


int loadImage(){
    imgSurface = SDL_LoadBMP("Test.bmp");
    if(imgSurface == NULL)
        return -1;
    else{

    }
    return 0;
}

int close(){
    SDL_FreeSurface(imgSurface);
    SDL_DestroyWindow(window);
    window = NULL;
    SDL_Quit();
    return 0;

}

`

【问题讨论】:

  • 另外,fprintf 不会在 stdout 和 stderr 流上显示任何内容
  • 调用非静态函数close 通常是一个非常糟糕的主意,因为它与libc 的close(int) 有别名,并且Xlib/SDL 可能会在尝试关闭其文件时调用您的函数描述符。这可能是您看不到任何打印内容的原因,也许更多。
  • 谢谢老兄,成功了!希望您将其发布为答案

标签: c codeblocks sdl-2


【解决方案1】:

尝试移动 close();在 while (run) 循环结束之后和 // Blitting nad 更新之前。 另外,移动 SDL_BlitSurface(imgSurface, NULL, scrsurface, NULL); SDL_UpdateWindowSurface(窗口);其他地方,因为它会在你的程序停止运行后运行,之后的所有代码也会在 run 设置为 0 时运行。

【讨论】:

  • 实际上,close() 就在 while(run) 循环结束之后,而 blitting 和其他东西都在循环内,所以是的......
  • 尝试从关闭函数中删除window = null
  • “不会关闭”是什么意思?当您将鼠标悬停在窗口上时,是否有一个加载圆圈(我不知道它在 linux 上是如何工作的,但是窗口是否会投影一个动画,指示它正在“加载”?)还是单击后窗口没有消失关闭按钮?
  • 它根本不会消失,fprintfs 也不会出现在控制台上,而且 close() 没有循环就可以正常工作,所以我怀疑这是问题所在
  • 但是您可以单击关闭按钮,对吗?尝试添加另一个输入,例如 SDL_KEYDOWN,
【解决方案2】:

虽然需要彻底调试才能确定到底发生了什么,但您的问题很可能是由 libc 的 close 函数和您的函数的别名引起的。 close 是许多库使用的非常重要的调用,包括 Xlib(由 SDL 调用)。例如。 SDL_CreateWindow 调用XOpenDisplay/XCloseDisplay 来测试显示能力,但XCloseDisplay 在其连接套接字上调用close,它会调用你的函数。很难说之后会发生什么,但肯定不是预期的结果。

解决方法是将函数重命名为其他名称(例如,通过给它一个前缀)或将其声明为 static,这样它的名称就不会被导出。请注意,静态函数只能在单个翻译单元中使用(即,如果您的 .c 文件包含静态函数,则不能轻松地从另一个 .c 文件中使用它)。

链接器不会在此处报告多个定义,因为 libc 的关闭是一个弱符号(nm -D /lib/libc.so.6 | egrep ' close$' 报告 W)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    • 2012-01-26
    相关资源
    最近更新 更多