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