J'ai un DLL où j'utilise AllocConsole () et cout pour afficher les données à des fins de débogage.
.
Je ne sais pas pourquoi cela se produit.
Des idées?
Une partie de mon 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;
Mais rien ne s'affiche.
Je me souviens vaguement que vous pourriez avoir besoin de rediriger la sortie standard vers la console. Je peux me tromper cependant (puisque votre code fonctionnait plus tôt):
AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "This works" << std::endl;
Cela fonctionne en utilisant vs2015 avec la ligne 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);
Après avoir alloué une nouvelle console via AllocConsole()
, vous devez rouvrir les flux standard (stdout
, stderr
, stdin
) avant de pouvoir les utiliser.
Vous pouvez le faire en utilisant freopen
(dans les versions plus récentes de Visual Studio, vous devez utiliser freopen_s
) Exemple:
FILE *fDummy;
freopen_s(&fDummy, "CONIN$", "r", stdin);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONOUT$", "w", stdout);
Si vous souhaitez utiliser le freopen
déprécié, vous pouvez désactiver l'avertissement en #define
Ing _CRT_SECURE_NO_WARNINGS
.
Si vous souhaitez également utiliser les flux de caractères larges (std::wcout
, std::wcerr
, Etc ...), vous devez appeler SetStdHandle()
pour définir un nouveau descripteur de sortie pour votre processus. Vous pouvez obtenir le descripteur de fichier requis pour cela en appelant CreateFile()
avec CONOUT$
/CONIN$
Comme nom de fichier:
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);
De plus, si vous avez essayé d'utiliser l'un des flux avant de les rouvrir, ils auront std::ios_base::badbit
et std::ios_base::failbit
définis dans leur iostate
, donc les écritures/lectures suivantes seront ignorées.
Vous pouvez réinitialiser l'état du flux avec .clear()
, après quoi vous pouvez à nouveau lire/écrire depuis/vers le flux:
std::cout.clear();
std::cin.clear();
Voici un exemple complet de réouverture de tous les flux après 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();
}