最近使用D3D11做开小车的网易-1任务, 程序的入口函数是WinMain函数, 无法使用cout进行调试, 蓝瘦香菇, 使用常规的项目属性-配置属性-链接器-系统-子系统-控制台大法依旧无果, 终于在stackoverflow觅得良方, 撒花✿✿ヽ(°▽°)ノ✿
参考材料
1. How do I get console output in C++ with a Windows program?
2. winmain和main入口函数比较
需要进行重定向, 虽然我也不大懂代码具体写了啥, 囧…… 反正能用就行, 管它咧233333
#ifndef __GUICON_H__ #define __GUICON_H__ #ifdef _DEBUG #include <iostream> void RedirectIOToConsole(); #endif #endif // End of File
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <fstream>
#include <guicon.h>
#ifndef _USE_OLD_IOSTREAMS
using namespace std;
#endif
// maximum mumber of lines the output console should have
static const WORD MAX_CONSOLE_LINES = 500;
#ifdef _DEBUG
void RedirectIOToConsole()
{
int hConHandle;
long lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
// allocate a console for this app
AllocConsole();
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = MAX_CONSOLE_LINES;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "r");
*stdin = *fp;
setvbuf(stdin, NULL, _IONBF, 0);
// redirect unbuffered STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stderr = *fp;
setvbuf(stderr, NULL, _IONBF, 0);
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
ios::sync_with_stdio();
// Get STDOUT handle
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
int SystemOutput = _open_osfhandle(intptr_t(ConsoleOutput), _O_TEXT);
FILE *COutputHandle = _fdopen(SystemOutput, "w");
// Get STDERR handle
HANDLE ConsoleError = GetStdHandle(STD_ERROR_HANDLE);
int SystemError = _open_osfhandle(intptr_t(ConsoleError), _O_TEXT);
FILE *CErrorHandle = _fdopen(SystemError, "w");
// Get STDIN handle
HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
int SystemInput = _open_osfhandle(intptr_t(ConsoleInput), _O_TEXT);
FILE *CInputHandle = _fdopen(SystemInput, "r");
//make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well
ios::sync_with_stdio(true);
// Redirect the CRT standard input, output, and error handles to the console
freopen_s(&CInputHandle, "CONIN$", "r", stdin);
freopen_s(&COutputHandle, "CONOUT$", "w", stdout);
freopen_s(&CErrorHandle, "CONOUT$", "w", stderr);
//Clear the error state for each of the C++ standard stream objects. We need to do this, as
//attempts to access the standard streams before they refer to a valid target will cause the
//iostream objects to enter an error state. In versions of Visual Studio after 2005, this seems
//to always occur during startup regardless of whether anything has been read from or written to
//the console or not.
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
std::wcin.clear();
std::cin.clear();
}
#endif
//End of File
#include "guicon.h"
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
#ifdef _DEBUG
RedirectIOToConsole();
#endif
std::cout<<"test"<<std::endl;
}
注记1: WinMain函数接收4个参数, 这些参数都是在系统调用WinMain函数时, 传递给应用程序的.
第一个参数hInstance表示该程序当前运行的实例的句柄, 这是一个数值. 当程序在Windows下运行时, 它唯一标识运行中的实例(注意, 只有运行中的程序实例, 才有实例句柄), 一个应用程序可以运行多个实例, 每运行一个实例, 系统都会给该实例分配一个句柄值, 并通过hInstance参数传递给WinMain函数.
第二个参数hPrevInstance(MSDN) 在Win32环境下, 这个参数不起作用, 历史遗留, hPrevInstance=NULL.
第三个参数lpCmdLine是一个以空(‘\0’) 终止的字符串, 指定传递给应用程序的命令行参数.
注记2: 运行参数, 例如在命令行键入: test.exe /install, 那么程序入口WinMain处, 其参数lpCmdLine就接收到了/install参数. 但是, 至于你用这个参数做什么, 那是用代码实现. 而实现安装, 这需要根据你的需求加入代码, 和命令行参数无关. 这个跟命令行的int main(int argc, char* argv[])不同.