![](/img/trans.png)
[英]Doing a std::endl before AllocConsole causes no display of std::cout
[英]AllocConsole() not displaying cout
我有一個DLL,我使用AllocConsole()和cout來顯示數據以進行調試。
它曾經工作正常但是因為我將我的編譯器(Visual Studio 2012)更新到最新的dll只顯示控制台而不是print / couts。
我不明白為什么會發生這種情況。
有任何想法嗎?
我的部分代碼
__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;
但是什么都沒有顯示
我隱約回想起你可能需要將stdout重定向到控制台。 我可能錯了(因為你的代碼工作得很早):
AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "This works" << std::endl;
這使用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);
通過AllocConsole()
分配新控制台后,您需要重新打開標准流( stdout
, stderr
, stdin
)才能使用它們。
您可以使用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);
如果要使用已棄用的freopen
,可以通過#define
ing _CRT_SECURE_NO_WARNINGS
禁用警告 。
如果您還想使用寬字符流( std::wcout
, std::wcerr
等...),則需要調用SetStdHandle()
為進程設置新的輸出句柄。 您可以通過使用CONOUT$
/ CONIN$
作為文件名調用CreateFile()
來獲取所需的文件句柄:
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);
此外,如果您在重新打開它們之前嘗試使用其中一個流,則它們將在其iostate
設置std::ios_base::badbit
和std::ios_base::failbit
,因此將忽略后續寫入/讀取。
您可以使用.clear()
重置流狀態,之后您可以再次從/讀取/寫入流:
std::cout.clear();
std::cin.clear();
下面是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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.