C++ AllocConsole()不显示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)

我有一个DLL,在其中我使用alloconsole()和cout显示数据以进行调试。
它以前工作得很好,但自从我将编译器(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);