SDL 用它自己的入口点覆盖程序入口点。
有关here、there 和over there 的更多详细信息。
默认情况下,标准输出 (stdout, stdin and stderr) 被重定向到文件,这些文件与它们所保存的流的内容具有相同的名称。
它们应该在您的程序目录中。
1 - 重定向流
要绕过该行为,您必须在 SDL_Init 之后插入以下内容。 如果 add after 不起作用,请尝试将它们添加到 main 的最顶部。
freopen ("CON", "w", stdout);
freopen ("CON", "r", stdin);
freopen ("CON", "w", stderr);
如果还是不行试试。
// Start : edit
SDL_Init (...)
FILE * ctt = fopen("CON", "w" ); // c
// or
ofstream ctt("CON"); // c++
// End : edit
freopen ("CON", "w", stdout);
freopen ("CON", "r", stdin);
freopen ("CON", "w", stderr);
/* ... */
// Start : edit
fclose (ctt); // c
// or
ctt.close(); // c++
// End : edit
了解 CON here。
根据我的阅读,“CON”似乎可以替换为 NULL。
(物有所值。)
freopen(NULL,"w",stdout);
freopen(NULL,"w",stdout);
freopen(NULL,"w",stderr);
freopen 方法的另一个变体。
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
更多关于 CONOUT$ 和 CONIN$ here。
如果您在使用 GNU/Linux BSD、Solaris、Mac Os 等之前遇到问题。请尝试以下操作。
freopen ("/dev/tty", "w", stdout);
freopen ("/dev/tty", "r", stdin);
freopen ("/dev/tty", "w", stderr);
应用该方法应如下面的代码所示。
/* ... */
int main {
SDL_Init(SDL_INIT_VIDEO);
/* start : redirecting the streams to the console */
FILE * ctt = fopen("CON", "w" ); // Edit
freopen ("CON", "w", stdout);
freopen ("CON", "r", stdin);
freopen ("CON", "w", stderr);
/* end : redirecting the streams to the console */
/*start : your code */
putenv("SDL_VIDEO_CENTERED=center");
SDL_WM_SetCaption("Railroad Builder",NULL);
SDL_WM_SetIcon(IMG_Load(strcat_const(parentFolder(exePath),
"/icon.png")),NULL);
SDL_SetVideoMode(MAIN_WINDOW_WIDTH,MAIN_WINDOW_HEIGHT,32,
SDL_OPENGL);
int running = 1;
while(running){
printf("myVar = %d",myVar);
}
/* end : your code */
/* ... */
fclose (ctt); // Edit
/* ... */
}
您可以在SDL faq 上找到该示例。
2 - 更改程序的入口点
您还可以取消定义 SDL 的 main,这样您的 main 将是第一个被调用的。
为此,请在 main 函数之前添加下一条指令。
/*...*/
#ifdef main
#undef main // Prevent SDL from overriding the program's entry point.
#endif
/***/
int main(int argc, char **argv){
/*...*/
}
或
/*...*/
#ifdef __MINGW32__ // It can be __MINGW64__. Chose according to your architecture.
#undef main // Prevent SDL from overriding the program's entry point.
#endif
//or
#if defined(__MINGW32__) || defined(__MINGW64__)
#undef main // Prevent SDL from overriding the program's entry point.
#endif
/*...*/
int main(int argc, char **argv){
/*...*/
}
关于MINGW32 and MINGW64
3 - 重建 SDL
使用从 SDL 站点下载的预编译 SDLmain.dll 二进制文件,您无法阻止 stdout/stderr 被重定向到文本文件。
您可以做的是使用 NO_STDIO_REDIRECT 编译器标志自己编译 SDLmain,或者根本不使用 SDLmain。
请注意,不使用 SDLmain 会破坏可移植性,不推荐使用。
也就是说,有时将 stdout.txt 和 stderr.txt 写入可执行文件所在的目录会更好。
你可以用一点技巧来做到这一点:
#include "SDL/SDL.h"
#ifdef WIN32
#include "sdl_winmain.h"
#else
#include "SDL/SDL_main.h"
#endif
其中 sdl_winmain.h 位于您自己的项目目录中,是 SDL 源包中 src/main/SDL_win32_main.c 的重写副本。这样,您仍然可以移植到其他平台,但不会在 windows 中到处获取 stdout/stderr 文件。
来自SDL faq。如需更多信息,请联系wikifriendly。
3.5 在源中
在源代码(~/SDL2-2.0.4/include/SDL_main.h)中,我发现了以下内容
#ifndef SDL_MAIN_HANDLED
#if defined(__WIN32__)
/* On Windows SDL provides WinMain(), which parses the command line and passes
the arguments to your main function.
If you provide your own WinMain(), you may define SDL_MAIN_HANDLED
*/
source code 的在线副本。
如果您没有成功定义 NO_STDIO_REDIRECT,请尝试 SDL_MAIN_HANDLED。
在 SDL-1.2.15 (~/SDL-1.2.15/include/SDL/SDL_main.h) 中找不到它,但是我发现的是
#define main SDL_main
这似乎与上面的#undef main 方法一致。
4 - 注意
将错误消息发送到 stderr 而不是 stdout 可能会很有趣。为此,请尝试使用 perror 或 fprintf。
像这样:
/*...*/
perror ("Error"); // the string cannot be formatted
fprintf (stderr,"Error %s", str_err_msg); // the string can be formatted
/*...*/