当SDL 2程序运行时,我该如何在控制台打印输出?

8
我想在运行SDL 2程序时将一些调试信息打印到控制台上,但似乎不可能。无论是printf("Hi!\n")还是SDL_Log("Hi!\n")都没有任何效果。
我甚至尝试在初始化SDL之前(以及退出之后)打印,但都没有用。似乎仅仅是导入SDL库就使得将任何内容打印到控制台变得不可能。
这是我编译的参数,因为这有可能与此有关:
g++ hello.cc -IC:\mingw_dev_lib\include\SDL2 -LC:\mingw_dev_lib\lib -w -Wl,-subsystem,windows -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -std=c++11

任何想法?

这可能是由于sdl2main库引起的。通常在普通的sdl程序中实际上并不需要它,但它会导致调试输出丢失的问题... - tp1
@tp1 你是在建议我删除sdl2main吗?我找到的最接近的东西是 libSDL2main.a,而删除该文件会导致更多问题。 - Coffee Maker
这可能是你在SDL中做的事情或者与平台相关的问题。我现在正在使用SDL2,在运行时立即通过cout打印没有任何问题。我也在Windows上使用MSYS2。 - user3995702
这不是非常明确,但可能会有所帮助:http://www.gamedev.net/topic/299349-cout-to-console-in-sdl/ - user3995702
我从其他网站上找到了答案,所以我会回答自己的问题。 - Coffee Maker
4个回答

7
所以,我找出了阻止我看到输出的原因。这些编译选项
-Wl,-subsystem,windows
基本上禁用了控制台窗口,防止输出被显示。这对于游戏完成后非常有用,但对于调试来说很糟糕。因此,我去掉了这些编译选项,现在printf()和SDL_Log()都可以正常工作。

如果有人正在使用pkg-config,您将需要保存输出并删除-mwindows。 - AntonioCS
谢谢!这个行为已经毁了我的一周。 - Wlliam

6

由于在使用mingw时,SDL2在Windows上仍然存在问题,所以这是我找到并测试过的更好的解决方案。

不要像其他人建议的那样删除-mwindows构建选项。你应该将`pkg-config --libs SDL2`添加为你的构建选项,但对于调试构建选项,你还应该在末尾添加-mconsole。它应该在-mwindows标志之后。

调试:`pkg-config --libs SDL2` -mconsole
发布:`pkg-config --libs SDL2`

注意:我正在编译Windows 10,SDL2 v2.0.9,Msys64,mingw64,Code::Blocks 17.12
`pkg-config --libs SDL2`扩展为:
-LC:/msys64/mingw64/lib -lmingw32 -lSDL2main -lSDL2 -mwindows

参考资料:
SDL2:在pkg-config --libs输出中保留-mwindows标志#2419
configure:在MinGW下链接SDL时强制使用-mconsole


0
我在调试控制台时使用这种方法:
static ULONG_PTR GetParentProcessId() // By Napalm @ NetCore2K
{
    ULONG_PTR pbi[6];
    ULONG ulSize = 0;
    LONG (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle, ULONG ProcessInformationClass,
            PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); 
    *(FARPROC *)&NtQueryInformationProcess = 
        GetProcAddress(LoadLibraryA("NTDLL.DLL"), "NtQueryInformationProcess");
    if(NtQueryInformationProcess){
        if(NtQueryInformationProcess(GetCurrentProcess(), 0,
                    &pbi, sizeof(pbi), &ulSize) >= 0 && ulSize == sizeof(pbi))
            return pbi[5];
    }
    return (ULONG_PTR)-1;
}

static void _windows_init_console(int argc, char **argv) {
    (void)argc, (void)argv;
    ULONG_PTR ppid = GetParentProcessId();
    if(ppid == (ULONG_PTR)-1) {
        AllocConsole();
    } else {
        AttachConsole(ppid);
    }

    freopen("CONIN$", "r", stdin); 
    freopen("CONOUT$", "w", stdout); 
    freopen("CONOUT$", "w", stderr); 
}

(GetParentProcessId 来自于 Win32 进程如何获取其父进程的 pid?)。它运行得相当不错,但我仍然无法让它与 grep/findstr 等一起使用(即通过管道重定向获得“真实”的标准输出)。


0

由于SDL2使用Windows子系统,您可以使用Win32 API打开控制台窗口。

根据这篇博客文章

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include <SDL2/SDL.h>

int main(int argc, char *argv[])
{
    // SDL2 init code...

    // Just before the event loop
    AllocConsole();

    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
    int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
    FILE* hf_out = _fdopen(hCrt, "w");
    setvbuf(hf_out, NULL, _IONBF, 1);
    *stdout = *hf_out;

    HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
    hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
    FILE* hf_in = _fdopen(hCrt, "r");
    setvbuf(hf_in, NULL, _IONBF, 128);
    *stdin = *hf_in;

    // use the console just like a normal one - printf(), getchar(), ...
}

希望这能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接