首页 > 解决方案 > 返回 0 后程序仍在运行;使用 SDL_Renderer

问题描述

我正在做关于 SDL 的 Lazy Foo 的教程(我使用的是 SDL2-2.0.9),在纹理渲染部分我遇到了以下问题:程序按预期编译和运行,这里没有问题,但是当我关闭窗口,控制台没有关闭,进程继续运行,所以我必须单独关闭控制台。

当我尝试调试它时,我发现程序确实离开了主循环并成功到达主函数中的“return 0”行,但随后它就这样挂起,直到我关闭控制台。

仅当我将 SDL 渲染器与 SDL_RENDERER_SOFTWARE 以外的任何选项一起使用时,才会出现此问题。如果我使用 SDL_RENDERER_SOFTWARE - 程序按预期关闭。对于其他选项,它保持在“返回 0”运行其他线程(crypt32.dll、ntdll.dll 和 nvd3dum,在线程视图中按此顺序,这意味着进程卡在 crypt32 中)。

我知道我的主要功能不是“真正的主要”,因为它已被 SDL 劫持,因此 exit(0) 作为临时解决方案可以正常工作。但我想知道,为什么会发生这种情况,还有其他方法可以解决这个问题,这样我就不必使用 exit(0) 了吗?

这是一个示例(简化)代码,它为我演示了这个问题:

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

int main(int argc, char *argv[]) {
    SDL_Window *win = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Texture *bitmapTex = NULL;
    SDL_Surface *bitmapSurface = NULL;
    int width = 640, height = 480;

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        printf("Could not initialize SDL");
        return 1;
    }

    win = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0);

    renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
    bitmapSurface = SDL_LoadBMP("res/x.bmp");
    bitmapTex = SDL_CreateTextureFromSurface(renderer, bitmapSurface);
    SDL_FreeSurface(bitmapSurface);

    bool quit = false;
    while (!quit) {
        SDL_Event e;
        while (SDL_PollEvent(&e) != 0) {
            if (e.type == SDL_QUIT) {
                quit = true;
            }
        }

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, bitmapTex, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyTexture(bitmapTex);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(win);

    SDL_Quit();

    printf("REACHED RETURN 0");
    return 0;

}

按预期工作,但在关闭窗口后,我看到控制台中打印了“REACHED RETURN 0”,就是这样,控制台停留在那里。代码可以进一步简化,只要创建了 SDL_Renderer 的实例,问题就会出现。

UPD:挂起期间的调用堆栈:

>   ntdll.dll!_NtWaitForMultipleObjects@20()    
    KernelBase.dll!_WaitForMultipleObjectsEx@20()   
    crypt32.dll!ILS_WaitForThreadProc() 
    kernel32.dll!@BaseThreadInitThunk@12()  
    ntdll.dll!__RtlUserThreadStart()    
    ntdll.dll!__RtlUserThreadStart@8()  

UPD2:问题根本不在于循环,我创建了最简单的应用程序,我只创建了一个窗口和一个渲染器,然后返回 0,它仍然给了我一个悬挂控制台。像这样:

#include <SDL.h>

int main(int argc, char* args[])
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0) return 1;
    SDL_Window* window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    return 0;
}

当我正确地摧毁它们时也是如此。问题出在渲染器中。

UPD3:这是“挂起”期间的并行堆栈窗口。因为我成功关闭它,所以没有“主”线程,这些是阻止程序正常关闭的线程。除此之外,它并没有让我对这个问题有任何理解。

标签: c++sdl

解决方案


推荐阅读