【问题标题】:How do I print to the console while an SDL 2 program is running?如何在 SDL 2 程序运行时打印到控制台?
【发布时间】:2016-04-04 23:53:16
【问题描述】:

我想在运行我的 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 你是在建议我删除 sdl2main 吗?我发现最接近的东西是libSDL2main.a,删除该文件会导致更多问题。
  • 这可能是您在 SDL 中所做的事情或与平台相关的问题。我现在正在使用 SDL2,并且在运行时立即通过 cout 打印没有问题。我也在 Windows 上使用 MSYS2。
  • 这不是很明确,但可能会有所帮助:gamedev.net/topic/299349-cout-to-console-in-sdl
  • 我是从其他网站发现的,所以我会继续回答我自己的问题。

标签: c++ windows mingw sdl-2


【解决方案1】:

所以,我找到了阻止我看到输出的原因。这些编译选项

-Wl,-subsystem,windows

基本上禁用控制台窗口,防止显示输出。这对于游戏完成时很有用,但对于调试来说却很糟糕。所以,我继续删除了那些编译选项,现在 printf()SDL_Log() 工作得很好。

【讨论】:

  • 如果有人使用 pkg-config,你必须保存输出并删除 -mwindows
  • 谢谢!这种行为毁了我的一周
【解决方案2】:

由于在使用 mingw 时 SDL2 在窗口中仍然存在问题,因此这是我发现并测试为有效的更好解决方案。

不要像其他人建议的那样删除 -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: keep the -mwindows flag in the pkg-config --libs output #2419
configure: force -mconsole when linking SDL under MinGW

【讨论】:

    【解决方案3】:

    我使用这种方法来调试控制台:

    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 来自 How can a Win32 process get the pid of its parent?)。工作得很好,但我仍然无法使其与grep/findstr 等一起工作(即带有管道重定向的“真”标准输出)。

    【讨论】:

      【解决方案4】:

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

      据此blog post

      #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(), ...
      }
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-31
        • 1970-01-01
        • 2018-07-28
        相关资源
        最近更新 更多