C++ AllocConsole() 不显示 cout
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15543571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AllocConsole() not displaying cout
提问by madziikoy
I have a DLL where I use AllocConsole() and cout to display data for debugging purposes.
It used to work fine but since I updated my compiler (Visual Studio 2012) to the latest the dll just shows the console but not the prints/couts.
I am out of idea's as to why this is happening.
Any idea's?
我有一个 DLL,我在其中使用 AllocConsole() 和 cout 来显示用于调试目的的数据。
它曾经可以正常工作,但自从我将编译器(Visual Studio 2012)更新到最新版本后,dll 只显示控制台,而不显示打印/输出。
我不知道为什么会这样。
有任何想法吗?
Part of my code
我的代码的一部分
__declspec(dllexport) INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
AllocConsole();
DisableThreadLibraryCalls(hDLL);
//
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pSend, MySend);
if(DetourTransactionCommit() == NO_ERROR)
cout << "[" << MySend << "] successfully detoured." << endl;
But nothing gets displayed.
但什么也没有显示。
回答by Vladimir Sinenko
I vaguely recall that you might need to redirect the stdout to the console. I might be wrong though (since you had your code working earlier):
我依稀记得您可能需要将标准输出重定向到控制台。我可能是错的(因为你的代码更早工作):
AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "This works" << std::endl;
回答by Turtlefight
After allocating a new console via AllocConsole()
, you need to re-open the standard streams (stdout
, stderr
, stdin
) before you can use them.
通过 分配新的控制台后AllocConsole()
,您需要重新打开标准流 ( stdout
, stderr
, stdin
) 才能使用它们。
You can do so by using freopen
(in newer versions of Visual Studio you need to use freopen_s
)
Example:
您可以使用freopen
(在您需要使用的较新版本的 Visual Studio 中freopen_s
)示例:
FILE *fDummy;
freopen_s(&fDummy, "CONIN$", "r", stdin);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONOUT$", "w", stdout);
If you want to use the deprecated freopen
you can disable the warningby #define
ing _CRT_SECURE_NO_WARNINGS
.
如果要使用已弃用的freopen
,可以通过ing禁用警告。#define
_CRT_SECURE_NO_WARNINGS
If you also want to use the wide-character streams (std::wcout
, std::wcerr
, etc...), you need to call SetStdHandle()
to set a new output handle for your process. You can get the required file handle for this by calling CreateFile()
with CONOUT$
/ CONIN$
as file name:
如果您还想使用宽字符流(std::wcout
、std::wcerr
等...),则需要调用SetStdHandle()
为您的进程设置新的输出句柄。您可以通过CreateFile()
使用CONOUT$
/CONIN$
作为文件名调用来获取所需的文件句柄:
HANDLE hConOut = CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetStdHandle(STD_OUTPUT_HANDLE, hConOut);
Additionally, if you tried to use one of the streams before re-opening them, they will have the std::ios_base::badbit
and std::ios_base::failbit
set in their iostate
, so subsequent writes / reads will be ignored.
You can reset the stream state with .clear()
, after which you can read/write from/to the stream again:
此外,如果您在重新打开流之前尝试使用其中一个流,它们的std::ios_base::badbit
和std::ios_base::failbit
将设置在它们的 中iostate
,因此后续的写入/读取将被忽略。
您可以使用 重置流状态.clear()
,之后您可以再次从/向流读取/写入:
std::cout.clear();
std::cin.clear();
Heres a full example of re-opening all the streams after AllocConsole()
:
下面是在 之后重新打开所有流的完整示例AllocConsole()
:
void CreateConsole()
{
if (!AllocConsole()) {
// Add some error handling here.
// You can call GetLastError() to get more info about the error.
return;
}
// std::cout, std::clog, std::cerr, std::cin
FILE* fDummy;
freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONIN$", "r", stdin);
std::cout.clear();
std::clog.clear();
std::cerr.clear();
std::cin.clear();
// std::wcout, std::wclog, std::wcerr, std::wcin
HANDLE hConOut = CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hConIn = CreateFile(_T("CONIN$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetStdHandle(STD_OUTPUT_HANDLE, hConOut);
SetStdHandle(STD_ERROR_HANDLE, hConOut);
SetStdHandle(STD_INPUT_HANDLE, hConIn);
std::wcout.clear();
std::wclog.clear();
std::wcerr.clear();
std::wcin.clear();
}
回答by Willy
This works using vs2015 with the line std::cout.clear()
这适用于使用 vs2015 的行std::cout.clear()
if (!AllocConsole())
MessageBox(NULL, L"The console window was not created", NULL, MB_ICONEXCLAMATION);
FILE* fp;
freopen_s(&fp, "CONOUT$", "w", stdout);
printf("Hello console on\n");
std::cout.clear();
std::cout << "Cout line one." << std::endl;
cout << "Cout line two." << std::endl;
MessageBox(NULL, (L"Pause to see console output."), (L"Pause Here"), MB_OK | MB_SYSTEMMODAL | MB_ICONEXCLAMATION);
fclose(fp);
if (!FreeConsole())
MessageBox(NULL, L"Failed to free the console!", NULL, MB_ICONEXCLAMATION);