C++ AllocConsole()不显示cout
我有一个DLL,在其中我使用alloconsole()和cout显示数据以进行调试。C++ AllocConsole()不显示cout,c++,dll,C++,Dll,我有一个DLL,在其中我使用alloconsole()和cout显示数据以进行调试。 它以前工作得很好,但自从我将编译器(Visual Studio 2012)更新到最新版本后,dll只显示控制台,而不显示打印/输出。 我不知道为什么会发生这种情况。 有什么想法吗 我代码的一部分 __declspec(dllexport) INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) { switch(Reason)
它以前工作得很好,但自从我将编译器(Visual Studio 2012)更新到最新版本后,dll只显示控制台,而不显示打印/输出。
我不知道为什么会发生这种情况。
有什么想法吗 我代码的一部分
__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;
\uuuuuu declspec(dllexport)intapientry DllMain(HMODULE hDLL,DWORD Reason,LPVOID Reserved)
{
切换(原因)
{
案例DLL\u进程\u附加:
allocsole();
禁用线程库调用(hDLL);
//
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
迂回附加(&(PVOID&)pSend,MySend);
if(DetourTransactionCommit()=无错误)
cout我隐约记得您可能需要将标准输出重定向到控制台。不过我可能错了(因为您之前的代码工作正常):
alloconsole();
freopen(“CONOUT$”、“w”、stdout);
std::cout这可以使用vs2015和行std::cout.clear()
if(!alloconsole())
MessageBox(NULL,L“控制台窗口未创建”,NULL,MB_图标连接);
文件*fp;
freopen_s(&fp,“CONOUT$”、“w”和stdout);
printf(“Hello console on\n”);
std::cout.clear();
std::cout通过分配新控制台后,需要重新打开标准流(stdout
,stderr
,stdin
),然后才能使用它们
您可以使用freopen
(在较新版本的Visual Studio中,您需要使用freopen\s
)
例如:
文件*fDummy;
freopen_s(&fDummy,“CONIN$”、“r”、stdin);
freopen_s(&fdumm,“CONOUT$”、“w”、stderr);
freopen_s(&fdumm,“CONOUT$”、“w”、stdout);
如果您想使用弃用的freopen
,您可以通过定义ing\u CRT\u SECURE\u NO\u警告
如果您还想使用宽字符流(std::wcout
,std::wcerr
,等等),则需要调用为您的进程设置新的输出句柄。您可以通过使用CONOUT$
/CONIN$
作为文件名调用来获取所需的文件句柄:
HANDLE hConOut=CreateFile(_T(“CONOUT$”),通用读取,通用写入,文件共享读取,文件共享写入,NULL,打开,文件属性正常,NULL);
设置TDHandle(标准输出句柄,hConOut);
此外,如果在重新打开流之前尝试使用其中一个流,则它们将具有和
在其iostate
中设置,因此后续写入/读取将被忽略。
您可以使用重置流状态,然后可以再次读取/写入流:
std::cout.clear();
std::cin.clear();
下面是在alloconsole()
之后重新打开所有流的完整示例:
void CreateConsole()
{
如果(!alloconsole()){
//在这里添加一些错误处理。
//您可以调用GetLastError()以获取有关错误的更多信息。
返回;
}
//标准::cout,标准::clog,标准::cerr,标准::cin
文件*fDummy;
freopen_s(&fdumm,“CONOUT$”、“w”、stdout);
freopen_s(&fdumm,“CONOUT$”、“w”、stderr);
freopen_s(&fDummy,“CONIN$”、“r”、stdin);
std::cout.clear();
std::clog.clear();
标准::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);
设置TDHandle(标准输出句柄,hConOut);
设置TDHandle(标准错误句柄,hConOut);
设置TDHandle(标准输入句柄,hConIn);
std::wcout.clear();
std::wclog.clear();
std::wcerr.clear();
std::wcin.clear();
}
freopen(“CONIN$”,“r”,stdin);
也能正常工作。由于freopen
是独立的(为了安全问题),您应该使用freopen\s(&new\u stdout,“CONOUT$”,“w”,stdout);
其中new stdout
是一个文件指针。freopen s((文件**)stdout,“CONOUT$”,“w”,stdout);
有没有办法打开两个控制台并向每个控制台写入不同的内容?@JerryJeremiah进程可以与之关联,但您当然可以创建一个子进程,然后它可以拥有自己的控制台(使用管道或其他形式的ipc将消息从父进程发送到子控制台)。或者,您可以使用不同的控制台并在不同控制台之间切换,但是您仍然需要子进程来为您创建这些控制台,因为每个进程只能创建一个控制台。
AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "This works" << std::endl;
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);